@leviyuan/lodestar 0.18.4 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lodestar.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as XK}from"node:module";var QK=Object.defineProperty;var VK=($)=>$;function HK($,Z){this[$]=VK.bind(null,Z)}var E$=($,Z)=>{for(var J in Z)QK($,J,{get:Z[J],enumerable:!0,configurable:!0,set:HK.bind(Z,J)})};var O=($,Z)=>()=>($&&(Z=$($=0)),Z);var zK=XK(import.meta.url);import{homedir as WK}from"node:os";import{join as n}from"node:path";function lJ($,Z,J){if($)return $;if(Z)return n(Z,"lodestar");return J}function GK(){if(uJ)return n(process.env.APPDATA??n(b9,"AppData","Roaming"),"Lodestar");return n(b9,".config","lodestar")}function KK(){if(uJ)return n(process.env.LOCALAPPDATA??n(b9,"AppData","Local"),"Lodestar");return n(b9,".local","share","lodestar")}var b9,uJ,V7,r,x0,o0,Y2,H7,X7,z7,W7,G7,C9,P1,k9,D1,Q2,dJ,iJ,nJ,K7,aJ,oJ,B7,_7,rJ,j7,F1,y9;var V0=O(()=>{b9=WK(),uJ=process.platform==="win32";V7=lJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,GK()),r=lJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,KK()),x0=process.env.LODESTAR_CONFIG??n(V7,"config.toml"),o0=n(r,"daemon.pid"),Y2=n(r,"daemon.log"),H7=n(r,"session-chat-map.json"),X7=n(r,"session-resume-map.json"),z7=n(r,"session-turns-map.json"),W7=n(r,"session-model-map.json"),G7=n(r,"temp-session-leases.json"),C9=n(r,"tasklist-map.json"),P1=n(r,"agent-runs"),k9=n(r,"agent-session-ids.json"),D1=n(r,"managed-claude-plugin"),Q2=n(r,"dsh"),dJ=n(r,"codex-accounts"),iJ=n(r,"codex-accounts.json"),nJ=n(r,"codex-quota-blocks.json"),K7=n(r,"agent-runtimes"),aJ=n(r,"context-window-cache.json"),oJ=n(r,"notify-callbacks.json"),B7=n(r,"alive-on-shutdown.json"),_7=n(r,"inbox"),rJ=n(r,"file-deliveries"),j7=n(r,"file-delivery-groups.json"),F1=n(r,"debug.sock"),y9=n(r,"debug-context.json")});import{execSync as sJ}from"node:child_process";import{readFileSync as tJ,writeFileSync as BK}from"node:fs";function _K(){return process.argv[1]??`pid:${process.pid}`}function jK($){try{if(process.platform==="linux")return tJ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return sJ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return sJ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function LK($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=jK($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function w9($){let Z="";try{Z=tJ($,"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(LK(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function eJ($){BK($,`${process.pid}
4
- ${_K()}`)}var L7=()=>{};import{execFile as qK}from"node:child_process";import{readFile as PK}from"node:fs/promises";import{homedir as DK}from"node:os";import{join as $Y}from"node:path";import{promisify as FK}from"node:util";import{Address4 as v9,Address6 as f9}from"ip-address";function V2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function m9($){let Z=$.hostname.replace(/^\[|\]$/g,"").toLowerCase();return Z==="localhost"||Z.endsWith(".localhost")||Z==="::1"||/^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(Z)||/^::ffff:(?:127\.|7f[0-9a-f]{2}:)/.test(Z)}function q7($,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(v9.isValid(V))return v9.isValid(J)&&new v9(J).isInSubnet(new v9(V));if(f9.isValid(V))return f9.isValid(J)&&new f9(J).isInSubnet(new f9(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 ZY($,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 JY($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(m9($)||q7($,V2(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=V2(Z,Y)||V2(Z,"ALL_PROXY");if(Q)return ZY(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(q7($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?ZY(V,"system settings"):void 0}function g9($,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 MK($){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 AK($){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=g9(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=g9(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=g9(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 h9($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function OK($){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=h9(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=h9(Z.get(`.${Q}/host`));if(!V)continue;let H=new URL(g9(V,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")H.username=h9(Z.get(".http/authentication-user")),H.password=h9(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 RK($){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 I9($,Z){let{stdout:J}=await UK($,Z,{encoding:"utf8",timeout:5000,maxBuffer:262144,windowsHide:!0});return J}async function TK(){if(process.platform==="win32")return MK(JSON.parse(await I9("powershell.exe",["-NoProfile","-NonInteractive","-Command",NK])));if(process.platform==="darwin")return AK(await I9("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=$Y(process.env.XDG_CONFIG_HOME||$Y(DK(),".config"),"kioslaverc");try{let J=RK(await PK($,"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 I9("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return OK(await I9("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function EK($=TK,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(m9(Q)||q7(Q,V2(Z,"NO_PROXY"))||V2(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||V2(Z,"ALL_PROXY"))return JY(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 JY(Q,Z,await Y.value)}}var UK,NK,YY;var QY=O(()=>{UK=FK(qK);NK=String.raw`
2
+ import{createRequire as LK}from"node:module";var BK=Object.defineProperty;var _K=($)=>$;function jK($,Z){this[$]=_K.bind(null,Z)}var N$=($,Z)=>{for(var J in Z)BK($,J,{get:Z[J],enumerable:!0,configurable:!0,set:jK.bind(Z,J)})};var O=($,Z)=>()=>($&&(Z=$($=0)),Z);var qK=LK(import.meta.url);import{homedir as PK}from"node:os";import{join as n}from"node:path";function aJ($,Z,J){if($)return $;if(Z)return n(Z,"lodestar");return J}function DK(){if(nJ)return n(process.env.APPDATA??n(x9,"AppData","Roaming"),"Lodestar");return n(x9,".config","lodestar")}function FK(){if(nJ)return n(process.env.LOCALAPPDATA??n(x9,"AppData","Local"),"Lodestar");return n(x9,".local","share","lodestar")}var x9,nJ,z7,r,E0,n0,e1,W7,G7,K7,B7,_7,S9,_1,C9,j1,$2,oJ,rJ,sJ,j7,tJ,eJ,L7,q7,$Y,P7,L1,b9;var V0=O(()=>{x9=PK(),nJ=process.platform==="win32";z7=aJ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,DK()),r=aJ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,FK()),E0=process.env.LODESTAR_CONFIG??n(z7,"config.toml"),n0=n(r,"daemon.pid"),e1=n(r,"daemon.log"),W7=n(r,"session-chat-map.json"),G7=n(r,"session-resume-map.json"),K7=n(r,"session-turns-map.json"),B7=n(r,"session-model-map.json"),_7=n(r,"temp-session-leases.json"),S9=n(r,"tasklist-map.json"),_1=n(r,"agent-runs"),C9=n(r,"agent-session-ids.json"),j1=n(r,"managed-claude-plugin"),$2=n(r,"dsh"),oJ=n(r,"codex-accounts"),rJ=n(r,"codex-accounts.json"),sJ=n(r,"codex-quota-blocks.json"),j7=n(r,"agent-runtimes"),tJ=n(r,"context-window-cache.json"),eJ=n(r,"notify-callbacks.json"),L7=n(r,"alive-on-shutdown.json"),q7=n(r,"inbox"),$Y=n(r,"file-deliveries"),P7=n(r,"file-delivery-groups.json"),L1=n(r,"debug.sock"),b9=n(r,"debug-context.json")});import{execSync as ZY}from"node:child_process";import{readFileSync as JY,writeFileSync as MK}from"node:fs";function UK(){return process.argv[1]??`pid:${process.pid}`}function AK($){try{if(process.platform==="linux")return JY(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return ZY(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return ZY(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function OK($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=AK($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function k9($){let Z="";try{Z=JY($,"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(OK(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function YY($){MK($,`${process.pid}
4
+ ${UK()}`)}var D7=()=>{};import{execFile as RK}from"node:child_process";import{readFile as NK}from"node:fs/promises";import{homedir as TK}from"node:os";import{join as QY}from"node:path";import{promisify as EK}from"node:util";import{Address4 as y9,Address6 as v9}from"ip-address";function Z2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function I9($){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 F7($,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(y9.isValid(V))return y9.isValid(J)&&new y9(J).isInSubnet(new y9(V));if(v9.isValid(V))return v9.isValid(J)&&new v9(J).isInSubnet(new v9(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 VY($,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 HY($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(I9($)||F7($,Z2(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=Z2(Z,Y)||Z2(Z,"ALL_PROXY");if(Q)return VY(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(F7($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?VY(V,"system settings"):void 0}function h9($,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 SK($){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 CK($){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=h9(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=h9(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=h9(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 w9($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function bK($){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=w9(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=w9(Z.get(`.${Q}/host`));if(!V)continue;let H=new URL(h9(V,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")H.username=w9(Z.get(".http/authentication-user")),H.password=w9(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 kK($){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 f9($,Z){let{stdout:J}=await xK($,Z,{encoding:"utf8",timeout:5000,maxBuffer:262144,windowsHide:!0});return J}async function vK(){if(process.platform==="win32")return SK(JSON.parse(await f9("powershell.exe",["-NoProfile","-NonInteractive","-Command",yK])));if(process.platform==="darwin")return CK(await f9("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=QY(process.env.XDG_CONFIG_HOME||QY(TK(),".config"),"kioslaverc");try{let J=kK(await NK($,"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 f9("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return bK(await f9("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function wK($=vK,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(I9(Q)||F7(Q,Z2(Z,"NO_PROXY"))||Z2(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||Z2(Z,"ALL_PROXY"))return HY(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 HY(Q,Z,await Y.value)}}var xK,yK,XY;var zY=O(()=>{xK=EK(RK);yK=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
- `;YY=EK()});import{Agent as xK}from"node:http";import{Agent as SK}from"node:https";import{Readable as VY}from"node:stream";import bK from"node-fetch";import{HttpProxyAgent as CK}from"http-proxy-agent";import{HttpsProxyAgent as kK}from"https-proxy-agent";function vK($,Z){if(!Z)return $.protocol==="https:"?wK:yK;return $.protocol==="https:"?new kK(Z):new CK(Z)}async function fK($,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 HY??=new X.Agent,await X.fetch($,{...Z,redirect:"manual",dispatcher:HY})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"}),Q=await bK($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?VY.fromWeb(Y.body):void 0,signal:Y.signal,agent:vK($,J),redirect:"manual"}),V=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:VY.toWeb(Q.body);return new Response(V,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function XY($,Z,J,Y=YY){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&&!m9(Q))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let X=J?void 0:await Y(Q),z=await fK(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 $0($,Z={}){return XY($,Z,!1)}function zY($,Z={}){return XY($,Z,!0)}var yK,wK,HY;var h0=O(()=>{QY();yK=new xK({keepAlive:!0}),wK=new SK({keepAlive:!0})});import{chmodSync as hK,closeSync as P7,fsyncSync as WY,mkdirSync as IK,openSync as GY,renameSync as gK,unlinkSync as mK,writeFileSync as pK}from"node:fs";import{randomUUID as cK}from"node:crypto";import{dirname as KY}from"node:path";function iK($){let Z=KY($);IK(Z,{recursive:!0,mode:dK})}function BY($,Z,J){iK($);let Y=`${$}.${process.pid}.${cK()}.tmp`,Q=null;try{Q=GY(Y,"wx",J),pK(Q,Z),WY(Q),P7(Q),Q=null,gK(Y,$);try{hK($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=GY(KY($),"r"),WY(V)}catch{}finally{if(V!==null)try{P7(V)}catch{}}}}catch(V){if(Q!==null)try{P7(Q)}catch{}try{mK(Y)}catch{}throw V}}function I0($,Z){BY($,Z,uK)}function _Y($,Z){BY($,Z,lK)}function s($,Z){I0($,JSON.stringify(Z,null,2)+`
45
- `)}var uK=384,lK=448,dK=448;var S0=()=>{};import{execFile as nK}from"node:child_process";import{spawn as aK}from"cross-spawn";function rK($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{nK("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 D7($,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??aK)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${oK}`],{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()},T=(S)=>new p9(`${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(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??rK)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),B.catch((b)=>D(T(b instanceof Error?b.message:String(b))))},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,b)=>{j=!0,clearTimeout(M),Z?.removeEventListener("abort",A);try{await B}catch(v){D(T(v instanceof Error?v.message:String(v)));return}if(G||S!==0)D(Error(`${G?.message??`npm install exited code=${S} signal=${b}`}
49
- ${W}`));else D()}),Z?.aborted)A()})}var oK="https://registry.npmjs.org",p9;var F7=O(()=>{p9=class p9 extends Error{}});import{createHash as sK,randomUUID as tK}from"node:crypto";import{createRequire as eK}from"node:module";import{existsSync as U7,readFileSync as LY}from"node:fs";import{mkdir as qY,mkdtemp as $B,readFile as PY,rename as DY,rm as K4,writeFile as FY}from"node:fs/promises";import{join as g0,isAbsolute as ZB}from"node:path";import{fileURLToPath as JB,pathToFileURL as YB}from"node:url";function UY($,Z=K7){let J=g0(Z,$,"current.json");if(!U7(J))return null;let Y=JSON.parse(LY(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!ZB(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function c9($){let Z=UY($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function M7($,Z){return eK(g0(c9($),"package.json")).resolve(Z)}function _4($,Z){let J=g0(c9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!U7(J))throw Error(`${$} executable missing: ${J}`);return J}async function MY(){return import(YB(M7("claude","@anthropic-ai/claude-agent-sdk")).href)}async function XB($,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 $0(`${HB}/${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 zB($,Z){let J={};if($!=="dsh"){let H=await Promise.all(B4[$].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(B4.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 n$($,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 jY($,Z){let J=g0($,`current-${tK()}.json`),Y;try{await FY(J,JSON.stringify(Z)+`
50
- `,{mode:384}),await n$(()=>DY(J,g0($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await n$(()=>K4(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${x$(Y)}; state temporary file cleanup failed: ${x$(Q)}`);throw Q}}}async function WB($,Z){let J=g0($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await qY(J);try{await n$(async()=>I0(g0(J,"pid"),String(process.pid)))}catch(Q){try{await n$(()=>K4(J,{recursive:!0}))}catch(V){throw AggregateError([Q,V],`${x$(Q)}; runtime update lock cleanup failed: ${x$(V)}`)}throw Q}return()=>n$(()=>K4(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let V=Number(await PY(g0(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 n$(()=>K4(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 u9($,Z={}){let J=Z.root??K7,Y=g0(J,$);await qY(Y,{recursive:!0,mode:448});let Q=await WB(Y,Z.signal),V,H,X=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let z=UY($,J),W=await zB($,Z.metadata??((q,P)=>XB(q,P,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(LY(JB(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},B=sK("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(W).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=g0(Y,B);if(!U7(_)){V=await $B(g0(Y,".install-")),await FY(g0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:W[B4[$][0]],private:!0,type:"module",dependencies:W,overrides:{...G,...$==="dsh"?W:{}}})+`
51
- `,{mode:384}),await(Z.install??D7)(V,Z.signal);for(let[P,D]of Object.entries(W)){let T=JSON.parse(await PY(g0(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 n$(()=>DY(q,_)),V=void 0}let j={directory:_,versions:W,checkedAt:Date.now()};return await jY(Y,j),Z.report?.(`${$}: ${B4[$][0]}@${W[B4[$][0]]}${z?.directory===_?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){H=z,X=z instanceof p9;try{await jY(Y,{checkedAt:Date.now(),error:x$(z)})}catch(W){throw H=AggregateError([z,W],`${x$(z)}; recording update failure also failed: ${x$(W)}`),H}throw z}finally{let z=[];if(V&&!X){let W=V;try{await n$(()=>K4(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(x$).join("; "))}}}function AY($,Z={}){let J=QB.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,V,H=setInterval(()=>{if(V)return;V=(Z.update??u9)(Y,{report:$,signal:Q.signal}).catch((X)=>$(`${Y} 自动更新未完成: ${x$(X)}`)).finally(()=>{V=void 0})},VB);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var QB,VB=21600000,HB="https://registry.npmjs.org",B4,x$=($)=>$ instanceof Error?$.message:String($);var H2=O(()=>{h0();V0();F7();S0();F7();QB=["codex","claude","dsh"],B4={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 RY;var OY=O(()=>{RY={scopes:{tenant:["verification:verification_information:readonly","tenant:tenant:readonly","im:message:send_as_bot","im:message","im:chat","im:chat:create","im:chat:delete","im:chat.members:read","im:chat.members:write_only","im:resource","im:message.urgent","im:message.group_msg","im:message.group_at_msg:readonly","cardkit:card:read","cardkit:card:write","drive:drive","drive:file:upload"],user:[]}}});var EY={};E$(EY,{runSetup:()=>TB});import{execFileSync as KB,spawn as d9}from"node:child_process";import{spawn as BB}from"cross-spawn";import{existsSync as O7,mkdirSync as TY,readFileSync as _B}from"node:fs";import{createInterface as jB}from"node:readline/promises";import{dirname as LB,join as R7}from"node:path";import{homedir as qB}from"node:os";import{fileURLToPath as PB}from"node:url";async function U1($,Z={}){while(!0){let J=Z.default?`${L.dim} [${Z.default}]${L.reset}`:"",Y=(await j4.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 DB($){let Z="═".repeat(58);console.log(`
44
+ `;XY=wK()});import{Agent as fK}from"node:http";import{Agent as hK}from"node:https";import{Readable as WY}from"node:stream";import IK from"node-fetch";import{HttpProxyAgent as gK}from"http-proxy-agent";import{HttpsProxyAgent as mK}from"https-proxy-agent";function uK($,Z){if(!Z)return $.protocol==="https:"?cK:pK;return $.protocol==="https:"?new mK(Z):new gK(Z)}async function lK($,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 GY??=new X.Agent,await X.fetch($,{...Z,redirect:"manual",dispatcher:GY})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"}),Q=await IK($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?WY.fromWeb(Y.body):void 0,signal:Y.signal,agent:uK($,J),redirect:"manual"}),V=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:WY.toWeb(Q.body);return new Response(V,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function KY($,Z,J,Y=XY){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&&!I9(Q))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let X=J?void 0:await Y(Q),z=await lK(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 $0($,Z={}){return KY($,Z,!1)}function BY($,Z={}){return KY($,Z,!0)}var pK,cK,GY;var f0=O(()=>{zY();pK=new fK({keepAlive:!0}),cK=new hK({keepAlive:!0})});import{chmodSync as dK,closeSync as M7,fsyncSync as _Y,mkdirSync as iK,openSync as jY,renameSync as nK,unlinkSync as aK,writeFileSync as oK}from"node:fs";import{randomUUID as rK}from"node:crypto";import{dirname as LY}from"node:path";function $B($){let Z=LY($);iK(Z,{recursive:!0,mode:eK})}function qY($,Z,J){$B($);let Y=`${$}.${process.pid}.${rK()}.tmp`,Q=null;try{Q=jY(Y,"wx",J),oK(Q,Z),_Y(Q),M7(Q),Q=null,nK(Y,$);try{dK($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=jY(LY($),"r"),_Y(V)}catch{}finally{if(V!==null)try{M7(V)}catch{}}}}catch(V){if(Q!==null)try{M7(Q)}catch{}try{aK(Y)}catch{}throw V}}function h0($,Z){qY($,Z,sK)}function PY($,Z){qY($,Z,tK)}function s($,Z){h0($,JSON.stringify(Z,null,2)+`
45
+ `)}var sK=384,tK=448,eK=448;var x0=()=>{};import{execFile as ZB}from"node:child_process";import{spawn as JB}from"cross-spawn";function QB($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{ZB("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 U7($,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??JB)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${YB}`],{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 g9(`${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??QB)(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(w){D(T(w instanceof Error?w.message:String(w)));return}if(G||S!==0)D(Error(`${G?.message??`npm install exited code=${S} signal=${C}`}
49
+ ${W}`));else D()}),Z?.aborted)A()})}var YB="https://registry.npmjs.org",g9;var A7=O(()=>{g9=class g9 extends Error{}});import{createHash as VB,randomUUID as HB}from"node:crypto";import{createRequire as XB}from"node:module";import{existsSync as O7,readFileSync as FY}from"node:fs";import{mkdir as MY,mkdtemp as zB,readFile as UY,rename as AY,rm as G4,writeFile as OY}from"node:fs/promises";import{join as I0,isAbsolute as WB}from"node:path";import{fileURLToPath as GB,pathToFileURL as KB}from"node:url";function RY($,Z=j7){let J=I0(Z,$,"current.json");if(!O7(J))return null;let Y=JSON.parse(FY(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!WB(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function m9($){let Z=RY($);if(Z?.error)throw Error(`${$} 更新失败: ${Z.error}`);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);return Z.directory}function R7($,Z){return XB(I0(m9($),"package.json")).resolve(Z)}function B4($,Z){let J=I0(m9($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!O7(J))throw Error(`${$} executable missing: ${J}`);return J}async function NY(){return import(KB(R7("claude","@anthropic-ai/claude-agent-sdk")).href)}async function LB($,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 $0(`${jB}/${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 qB($,Z){let J={};if($!=="dsh"){let H=await Promise.all(K4[$].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(K4.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 l$($,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 DY($,Z){let J=I0($,`current-${HB()}.json`),Y;try{await OY(J,JSON.stringify(Z)+`
50
+ `,{mode:384}),await l$(()=>AY(J,I0($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await l$(()=>G4(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${T$(Y)}; state temporary file cleanup failed: ${T$(Q)}`);throw Q}}}async function PB($,Z){let J=I0($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await MY(J);try{await l$(async()=>h0(I0(J,"pid"),String(process.pid)))}catch(Q){try{await l$(()=>G4(J,{recursive:!0}))}catch(V){throw AggregateError([Q,V],`${T$(Q)}; runtime update lock cleanup failed: ${T$(V)}`)}throw Q}return()=>l$(()=>G4(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let V=Number(await UY(I0(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 l$(()=>G4(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 p9($,Z={}){let J=Z.root??j7,Y=I0(J,$);await MY(Y,{recursive:!0,mode:448});let Q=await PB(Y,Z.signal),V,H,X=!1;try{Z.report?.(`${$}: 检查 upstream latest`);let z=RY($,J),W=await qB($,Z.metadata??((q,P)=>LB(q,P,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(FY(GB(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},B=VB("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(W).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=I0(Y,B);if(!O7(_)){V=await zB(I0(Y,".install-")),await OY(I0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:W[K4[$][0]],private:!0,type:"module",dependencies:W,overrides:{...G,...$==="dsh"?W:{}}})+`
51
+ `,{mode:384}),await(Z.install??U7)(V,Z.signal);for(let[P,D]of Object.entries(W)){let T=JSON.parse(await UY(I0(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 l$(()=>AY(q,_)),V=void 0}let j={directory:_,versions:W,checkedAt:Date.now()};return await DY(Y,j),Z.report?.(`${$}: ${K4[$][0]}@${W[K4[$][0]]}${z?.directory===_?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){H=z,X=z instanceof g9;try{await DY(Y,{checkedAt:Date.now(),error:T$(z)})}catch(W){throw H=AggregateError([z,W],`${T$(z)}; recording update failure also failed: ${T$(W)}`),H}throw z}finally{let z=[];if(V&&!X){let W=V;try{await l$(()=>G4(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(T$).join("; "))}}}function TY($,Z={}){let J=BB.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,V,H=setInterval(()=>{if(V)return;V=(Z.update??p9)(Y,{report:$,signal:Q.signal}).catch((X)=>$(`${Y} 自动更新未完成: ${T$(X)}`)).finally(()=>{V=void 0})},_B);return H.unref(),()=>{clearInterval(H),Q.abort()}});return()=>{for(let Y of J)Y()}}var BB,_B=21600000,jB="https://registry.npmjs.org",K4,T$=($)=>$ instanceof Error?$.message:String($);var J2=O(()=>{f0();V0();A7();x0();A7();BB=["codex","claude","dsh"],K4={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 xY;var EY=O(()=>{xY={scopes:{tenant:["verification:verification_information:readonly","tenant:tenant:readonly","im:message:send_as_bot","im:message","im:chat","im:chat:create","im:chat:delete","im:chat.members:read","im:chat.members:write_only","im:resource","im:message.urgent","im:message.group_msg","im:message.group_at_msg:readonly","cardkit:card:read","cardkit:card:write","drive:drive","drive:file:upload"],user:[]}}});var bY={};N$(bY,{runSetup:()=>vB});import{execFileSync as FB,spawn as u9}from"node:child_process";import{spawn as MB}from"cross-spawn";import{existsSync as T7,mkdirSync as CY,readFileSync as UB}from"node:fs";import{createInterface as AB}from"node:readline/promises";import{dirname as OB,join as E7}from"node:path";import{homedir as RB}from"node:os";import{fileURLToPath as NB}from"node:url";async function q1($,Z={}){while(!0){let J=Z.default?`${L.dim} [${Z.default}]${L.reset}`:"",Y=(await _4.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 TB($){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
- `)}function l9($,Z,J){console.log(`
54
+ `)}function c9($,Z,J){console.log(`
55
55
  ${L.bold}${L.yellow}[${$}/${Z}] ${J}${L.reset}
56
- `)}function A7($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function NY($){try{let Z=KB($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function FB($){return new Promise((Z)=>{let J=BB($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function UB(){return process.env.CLAUDE_CONFIG_DIR||R7(qB(),".claude")}async function MB($){try{let Z=await $0("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 AB($){try{let Z=UB();TY(Z,{recursive:!0});let J=R7(Z,"settings.json"),Y={};if(O7(J)){let X=_B(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 MB($);if(H)Object.assign(V,H);return Y.env={...Q,...V},I0(J,JSON.stringify(Y,null,2)+`
57
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function OB($){try{if(process.platform==="win32")d9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")d9("open",[$],{detached:!0,stdio:"ignore"}).unref();else d9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function RB($,Z){try{let Y=await(await $0("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 NB(){try{let $=LB(PB(import.meta.url)),Z=R7($,"lodestar.js");if(!O7(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=d9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function TB(){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(O7(x0)){if(console.log(`${L.yellow}发现已有配置: ${x0}${L.reset}`),(await U1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),j4.close();return}}DB("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log("支持本机已登录的 Claude Code 订阅,也可配置 GLM Coding Plan 或 Anthropic API key。"),console.log("Claude Code 订阅与第三方来源可在 model 面板中分别选择。"),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 j4.question(`${L.dim}按 Enter 开始 (Ctrl+C 退出)...${L.reset}`),l9(1,4,"准备 Claude Code CLI"),await u9("claude",{report:(B)=>console.log(B)}),console.log(`${L.green}✓ Claude Code / SDK 已更新${L.reset}: ${L.dim}${_4("claude","claude")}${L.reset}`),console.log(),console.log(`${L.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${L.reset}`),console.log(`${L.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${L.reset}`),l9(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 订阅或其他已有配置。${L.reset}`),console.log();let $=await U1("GLM API key (直接回车跳过)",{});if($){let B=await AB($);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 U1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await u9("codex",{report:(_)=>console.log(_)});let B=_4("codex","codex");if(NY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else if(console.log(`${L.dim}启动 \`codex login\`...${L.reset}`),await FB(B)&&NY(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}`);l9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${L.cyan}${J}${L.reset}`),OB(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}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${L.reset}`),console.log(JSON.stringify(RY,null,2)),console.log(` ${L.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${L.reset}`),console.log(` ${L.dim}清单包含以下用途;也可按名称逐项开通:${L.reset}`),console.log(` ${L.dim}账号与认证信息 (排障):${L.reset}`),console.log(` • ${L.bold}verification:verification_information:readonly${L.reset} ${L.dim}# 查看账号主体认证状态${L.reset}`),console.log(` • ${L.bold}tenant:tenant:readonly${L.reset} ${L.dim}# 查看租户基本信息${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(` ${L.dim}云空间交付 (权限预先开通,功能仍按群开启):${L.reset}`),console.log(` • ${L.bold}drive:drive${L.reset} ${L.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${L.reset}`),console.log(` • ${L.bold}drive:file:upload${L.reset} ${L.dim}# 文件夹改名接口单独要求此权限${L.reset}`),console.log(` ${L.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${L.reset}`),console.log(` ${L.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${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 U1("App ID (以 cli_ 开头)",{required:!0}),Q=await U1("App Secret",{required:!0}),console.log(`${L.dim}测试中... (调 tenant_access_token endpoint)${L.reset}`);let B=await RB(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 U1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${L.yellow}已取消, 配置未写盘。${L.reset}`),j4.close(),process.exit(1)}l9(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 U1("projects_root",{default:V});TY(V7,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${A7(Y)}"`,`app_secret = "${A7(Q)}"`,"","[runtime]",`projects_root = "${A7(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];I0(x0,X.join(`
56
+ `)}function N7($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function SY($){try{let Z=FB($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function EB($){return new Promise((Z)=>{let J=MB($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function xB(){return process.env.CLAUDE_CONFIG_DIR||E7(RB(),".claude")}async function SB($){try{let Z=await $0("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 CB($){try{let Z=xB();CY(Z,{recursive:!0});let J=E7(Z,"settings.json"),Y={};if(T7(J)){let X=UB(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 SB($);if(H)Object.assign(V,H);return Y.env={...Q,...V},h0(J,JSON.stringify(Y,null,2)+`
57
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function bB($){try{if(process.platform==="win32")u9(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")u9("open",[$],{detached:!0,stdio:"ignore"}).unref();else u9("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function kB($,Z){try{let Y=await(await $0("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 yB(){try{let $=OB(NB(import.meta.url)),Z=E7($,"lodestar.js");if(!T7(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=u9(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function vB(){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(T7(E0)){if(console.log(`${L.yellow}发现已有配置: ${E0}${L.reset}`),(await q1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),_4.close();return}}TB("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log("支持本机已登录的 Claude Code 订阅,也可配置 GLM Coding Plan 或 Anthropic API key。"),console.log("Claude Code 订阅与第三方来源可在 model 面板中分别选择。"),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 _4.question(`${L.dim}按 Enter 开始 (Ctrl+C 退出)...${L.reset}`),c9(1,4,"准备 Claude Code CLI"),await p9("claude",{report:(B)=>console.log(B)}),console.log(`${L.green}✓ Claude Code / SDK 已更新${L.reset}: ${L.dim}${B4("claude","claude")}${L.reset}`),console.log(),console.log(`${L.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${L.reset}`),console.log(`${L.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${L.reset}`),c9(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 订阅或其他已有配置。${L.reset}`),console.log();let $=await q1("GLM API key (直接回车跳过)",{});if($){let B=await CB($);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 q1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await p9("codex",{report:(_)=>console.log(_)});let B=B4("codex","codex");if(SY(B))console.log(`${L.green}✓ Codex 已登录 ChatGPT${L.reset}`);else if(console.log(`${L.dim}启动 \`codex login\`...${L.reset}`),await EB(B)&&SY(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}`);c9(3,4,"Feishu 自建应用");let J="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${L.cyan}${J}${L.reset}`),bB(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}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${L.reset}`),console.log(JSON.stringify(xY,null,2)),console.log(` ${L.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${L.reset}`),console.log(` ${L.dim}清单包含以下用途;也可按名称逐项开通:${L.reset}`),console.log(` ${L.dim}账号与认证信息 (排障):${L.reset}`),console.log(` • ${L.bold}verification:verification_information:readonly${L.reset} ${L.dim}# 查看账号主体认证状态${L.reset}`),console.log(` • ${L.bold}tenant:tenant:readonly${L.reset} ${L.dim}# 查看租户基本信息${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(` ${L.dim}云空间交付 (权限预先开通,功能仍按群开启):${L.reset}`),console.log(` • ${L.bold}drive:drive${L.reset} ${L.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${L.reset}`),console.log(` • ${L.bold}drive:file:upload${L.reset} ${L.dim}# 文件夹改名接口单独要求此权限${L.reset}`),console.log(` ${L.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${L.reset}`),console.log(` ${L.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${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 q1("App ID (以 cli_ 开头)",{required:!0}),Q=await q1("App Secret",{required:!0}),console.log(`${L.dim}测试中... (调 tenant_access_token endpoint)${L.reset}`);let B=await kB(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 q1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${L.yellow}已取消, 配置未写盘。${L.reset}`),_4.close(),process.exit(1)}c9(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 q1("projects_root",{default:V});CY(z7,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${N7(Y)}"`,`app_secret = "${N7(Q)}"`,"","[runtime]",`projects_root = "${N7(H)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];h0(E0,X.join(`
58
58
  `)),console.log(`
59
- ${L.green}${L.bold}✓ 配置已写入${L.reset}`),console.log(` ${L.cyan}${x0}${L.reset}`),console.log(`
60
- ${L.bold}启动 daemon...${L.reset}`);let z=NB(),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(),j4.close()}var L,j4;var xY=O(()=>{h0();V0();S0();H2();OY();L={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},j4=jB({input:process.stdin,output:process.stdout})});import{existsSync as EB,readFileSync as xB}from"node:fs";function SY($,Z){return`${$}:${Z}`}function SB(){if(!EB(k9))return;try{let $=JSON.parse(xB(k9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");L4=new Set($.ids)}catch($){N7=$ instanceof Error?$:Error(String($))}}function bY(){if(N7)throw Error(`delegated-agent session registry is unavailable: ${N7.message}`)}function CY($,Z){bY();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=SY($,J);if(L4.has(Y))return;let Q=new Set(L4);Q.add(Y),s(k9,{version:1,ids:[...Q].sort()}),L4=Q}function X2($,Z){return bY(),L4.has(SY($,Z))}var L4,N7=null;var q4=O(()=>{V0();S0();L4=new Set;SB()});var kY=1;import{appendFileSync as vY,mkdirSync as bB,readdirSync as CB,unlinkSync as fY,existsSync as yY,statSync as kB,renameSync as yB,readFileSync as wB}from"node:fs";import{join as hY}from"node:path";function x7($="development"){return $!=="test"}function IY($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function gY($,Z=r){return hY(Z,`${T7}${IY($)}${E7}`)}function fB($){if(!$.startsWith(T7)||!$.endsWith(E7))return null;let Z=$.slice(T7.length,$.length-E7.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 mY($,Z=new Date,J=vB){let Y;try{Y=CB($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let H of Y){let X=fB(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{fY(hY($,H)),V++}catch{}}return V}function hB(){try{if(!yY(Y2))return;let $=kB(Y2);if(!$.isFile()||$.size===0)return;let Z=gY($.mtime);if(yY(Z)){vY(Z,wB(Y2)),fY(Y2);return}yB(Y2,Z)}catch{}}function K($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
- `;if(process.stderr.write(J),!x7())return;try{let Y=IY(Z);if(wY!==Y)wY=Y,mY(r,Z);vY(gY(Z),J)}catch{}}var vB=7,T7="daemon-",E7=".log",wY=null;var f=O(()=>{V0();if(x7())try{bB(r,{recursive:!0})}catch{}if(x7()){hB();try{mY(r)}catch{}}});import{EventEmitter as IB}from"node:events";import{createRequire as gB}from"node:module";import{createHash as mB,randomUUID as pB}from"node:crypto";import{createInterface as cB}from"node:readline";import{dirname as uB,join as S$,isAbsolute as lB}from"node:path";import{fileURLToPath as S7}from"node:url";import{tmpdir as dB}from"node:os";import{existsSync as pY,mkdirSync as cY,mkdtempSync as iB,readFileSync as P4,renameSync as nB,writeFileSync as uY,rmSync as b7}from"node:fs";import aB from"cross-spawn";function oB($){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 rB($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=P4(S$($,".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 z2($,Z,J={}){let Y=new i9($);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 i9;var D4=O(()=>{V0();H2();f();i9=class i9 extends IB{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!lB($.cwd))throw Error("DSH requires an absolute workspace");let Z=c9("dsh"),Y=gB(S$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(P4(Y,"utf8"));K(`dsh runtime: ${Q.version} (${Z})`);let V=oB($.env),H=$.home??Q2;cY(H,{recursive:!0,mode:448});let X=rB($.cwd,$.profile);this.launchDir=iB(S$(dB(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),W=z?"dsh-bridge.ts":"dsh-bridge.js",G=P4(S7(new URL(`./${W}`,import.meta.url))),B=z?P4(S7(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(P4(S7(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),q=mB("sha256").update(G).update(B).update(j).digest("hex").slice(0,20),P=S$(Z,".lodestar-bridges",q);cY(P,{recursive:!0});let D=S$(P,W),T=(y,g)=>{if(pY(y))return;let x=`${y}.${pB()}.tmp`;try{uY(x,g),nB(x,y)}finally{if(pY(x))b7(x)}};if(T(S$(P,"package.json"),j),z)T(S$(P,"dsh-protocol.ts"),B);T(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=S$(this.launchDir,"bridge.patch.yml");uY(A,JSON.stringify(U),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",S=[S$(uB(Y),Q.bin.dsh),"--profile","sdk","--patch",A,...($.patches??[]).flatMap((y)=>["--patch",y])],b={...$.env};if(b.LODESTAR_AGENT_CAPABILITY&&b.LODESTAR_AGENT_URL)b.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:b.LODESTAR_AGENT_URL,capability:b.LODESTAR_AGENT_CAPABILITY});for(let y of Object.keys(b))if(y.startsWith("LODESTAR_AGENT_"))delete b[y];try{this.child=aB(M,S,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...b,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(y){throw b7(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 v=cB({input:this.child.stdout,crlfDelay:1/0});v.on("line",(y)=>this.receive(y)),this.exitTask=new Promise((y)=>{this.child.once("error",(g)=>this.transportFailure(g)),this.child.once("close",(g,x)=>{this.exited=!0,v.close();let I=Error(`DSH exited code=${g} signal=${x}
62
- ${this.stderr}`);this.rejectPending(I),b7(this.launchDir,{recursive:!0,force:!0}),y(),this.emit("exit",{code:g,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!==kY||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}${E0}${L.reset}`),console.log(`
60
+ ${L.bold}启动 daemon...${L.reset}`);let z=yB(),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(),_4.close()}var L,_4;var kY=O(()=>{f0();V0();x0();J2();EY();L={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},_4=AB({input:process.stdin,output:process.stdout})});import{existsSync as wB,readFileSync as fB}from"node:fs";function yY($,Z){return`${$}:${Z}`}function hB(){if(!wB(C9))return;try{let $=JSON.parse(fB(C9,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");j4=new Set($.ids)}catch($){x7=$ instanceof Error?$:Error(String($))}}function vY(){if(x7)throw Error(`delegated-agent session registry is unavailable: ${x7.message}`)}function wY($,Z){vY();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=yY($,J);if(j4.has(Y))return;let Q=new Set(j4);Q.add(Y),s(C9,{version:1,ids:[...Q].sort()}),j4=Q}function Y2($,Z){return vY(),j4.has(yY($,Z))}var j4,x7=null;var L4=O(()=>{V0();x0();j4=new Set;hB()});var fY=1;import{appendFileSync as gY,mkdirSync as IB,readdirSync as gB,unlinkSync as mY,existsSync as hY,statSync as mB,renameSync as pB,readFileSync as cB}from"node:fs";import{join as pY}from"node:path";function b7($="development"){return $!=="test"}function cY($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function uY($,Z=r){return pY(Z,`${S7}${cY($)}${C7}`)}function lB($){if(!$.startsWith(S7)||!$.endsWith(C7))return null;let Z=$.slice(S7.length,$.length-C7.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 lY($,Z=new Date,J=uB){let Y;try{Y=gB($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let H of Y){let X=lB(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{mY(pY($,H)),V++}catch{}}return V}function dB(){try{if(!hY(e1))return;let $=mB(e1);if(!$.isFile()||$.size===0)return;let Z=uY($.mtime);if(hY(Z)){gY(Z,cB(e1)),mY(e1);return}pB(e1,Z)}catch{}}function K($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
+ `;if(process.stderr.write(J),!b7())return;try{let Y=cY(Z);if(IY!==Y)IY=Y,lY(r,Z);gY(uY(Z),J)}catch{}}var uB=7,S7="daemon-",C7=".log",IY=null;var f=O(()=>{V0();if(b7())try{IB(r,{recursive:!0})}catch{}if(b7()){dB();try{lY(r)}catch{}}});import{EventEmitter as iB}from"node:events";import{createRequire as nB}from"node:module";import{createHash as aB,randomUUID as oB}from"node:crypto";import{createInterface as rB}from"node:readline";import{dirname as sB,join as E$,isAbsolute as tB}from"node:path";import{fileURLToPath as k7}from"node:url";import{tmpdir as eB}from"node:os";import{existsSync as dY,mkdirSync as iY,mkdtempSync as $_,readFileSync as q4,renameSync as Z_,writeFileSync as nY,rmSync as y7}from"node:fs";import J_ from"cross-spawn";function Y_($){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 Q_($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=q4(E$($,".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 Q2($,Z,J={}){let Y=new l9($);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 l9;var P4=O(()=>{V0();J2();f();l9=class l9 extends iB{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!tB($.cwd))throw Error("DSH requires an absolute workspace");let Z=m9("dsh"),Y=nB(E$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(q4(Y,"utf8"));K(`dsh runtime: ${Q.version} (${Z})`);let V=Y_($.env),H=$.home??$2;iY(H,{recursive:!0,mode:448});let X=Q_($.cwd,$.profile);this.launchDir=$_(E$(eB(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),W=z?"dsh-bridge.ts":"dsh-bridge.js",G=q4(k7(new URL(`./${W}`,import.meta.url))),B=z?q4(k7(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(q4(k7(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),q=aB("sha256").update(G).update(B).update(j).digest("hex").slice(0,20),P=E$(Z,".lodestar-bridges",q);iY(P,{recursive:!0});let D=E$(P,W),T=(y,g)=>{if(dY(y))return;let x=`${y}.${oB()}.tmp`;try{nY(x,g),Z_(x,y)}finally{if(dY(x))y7(x)}};if(T(E$(P,"package.json"),j),z)T(E$(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=E$(this.launchDir,"bridge.patch.yml");nY(A,JSON.stringify(M),{mode:384});let U=$.env.LODESTAR_DSH_NODE||"node",S=[E$(sB(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=J_(U,S,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...C,DSH_HOME:H,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(y){throw y7(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 w=rB({input:this.child.stdout,crlfDelay:1/0});w.on("line",(y)=>this.receive(y)),this.exitTask=new Promise((y)=>{this.child.once("error",(g)=>this.transportFailure(g)),this.child.once("close",(g,x)=>{this.exited=!0,w.close();let I=Error(`DSH exited code=${g} signal=${x}
62
+ ${this.stderr}`);this.rejectPending(I),y7(this.launchDir,{recursive:!0,force:!0}),y(),this.emit("exit",{code:g,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!==fY||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 _$($){return typeof $==="string"&&C7.includes($)}function B0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function U0($){return typeof $==="string"&&k7.includes($)}function W2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function j$($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var C7,k7,a$="max",M1;var _0=O(()=>{C7=["codex","claude","dsh"];k7=["low","medium","high","xhigh","max","default"];M1=class M1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as sB}from"node:fs";import{homedir as dY}from"node:os";function lY($){return $.replace(/^~(?=\/|$)/,dY())}function tB($){let Z={_:{}},J="_";for(let Y of $.split(`
65
- `)){let Q=eB(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 eB($){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 n9(){let $;try{$=sB(x0,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${x0}
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 j$($){return typeof $==="string"&&v7.includes($)}function K0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function D0($){return typeof $==="string"&&w7.includes($)}function V2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function L$($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var v7,w7,d$="max",P1;var B0=O(()=>{v7=["codex","claude","dsh"];w7=["low","medium","high","xhigh","max","default"];P1=class P1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});import{readFileSync as V_}from"node:fs";import{homedir as oY}from"node:os";function aY($){return $.replace(/^~(?=\/|$)/,oY())}function H_($){let Z={_:{}},J="_";for(let Y of $.split(`
65
+ `)){let Q=X_(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 X_($){let Z=null,J=!1;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==="double"){if(J){J=!1;continue}if(Q==="\\"){J=!0;continue}if(Q==='"')Z=null;continue}if(Z==="single"){if(Q==="'")Z=null;continue}if(Q==='"')Z="double";else if(Q==="'")Z="single";else if(Q==="#")return $.slice(0,Y)}return $}function d9(){let $;try{$=V_(E0,"utf8")}catch(U){throw process.stderr.write(`lodestar: cannot read config at ${E0}
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=tB($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${x0} is missing [feishu].app_id / [feishu].app_secret`);let Q=lY(Z.runtime?.projects_root??dY()),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]??{},b={};for(let[v,y]of Object.entries(S))if(typeof y==="string"&&y.length>0)b[v]=y;return b},q=()=>{let M={};for(let[S,b]of Object.entries(Z)){if(!S.startsWith("claude.models."))continue;let y=S.slice(14).trim();if(!y)continue;let g={};for(let[x,I]of Object.entries(b)){if(typeof I!=="string"||I.length===0)continue;if(x.trim()==="model")g.model=I}M[y]=g}return M},P=()=>{let M={},S="projects.";for(let[b,v]of Object.entries(Z)){if(!b.startsWith("projects."))continue;let y=b.slice(9).trim();if(!y)continue;let g={};for(let[x,I]of Object.entries(v)){if(typeof I!=="string"||I.length===0)continue;switch(x.trim()){case"cwd":g.cwd=I;break;case"setting_sources":g.settingSources=I;break;case"strict_mcp":g.strictMcp=I==="true";break;case"tools":g.tools=I;break;case"load_project_mcp":g.loadProjectMcp=I==="true";break}}M[y]=g}return M},D=()=>{let M={},S="token_source.";for(let[b,v]of Object.entries(Z)){if(!b.startsWith("token_source."))continue;let y=b.slice(13).trim();if(!y)continue;let g={};for(let[x,I]of Object.entries(v)){if(typeof I!=="string")continue;let p=x.trim();if(p==="default")g.default=I==="true";else if(p==="agent"||p==="display"||p==="auth"||p==="base_url"||p==="auth_token"||p==="api_key"||p==="bin"||p==="model"||p==="effort"||p==="models"||p==="hidden_models"||p==="custom_models"||p==="slots"||p==="usage")g[p]=I}M[y]=g}return M},T=j("codex.env"),U=j("claude.env"),A=Z.claude?.bin?lY(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:U,models:q()},projects:P(),token_sources:D()}}function iY(){h.token_sources=n9().token_sources}var h;var y0=O(()=>{V0();h=n9()});function W0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function b$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function a9($){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 Z_($){let Z=$.slice(0,v7),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function J_($){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)??(F4(Z.type)?Z:null)??(J&&F4(J.type)?J:null)??(Y&&F4(Y.type)?Y:null)}function Y_($){let Z=[],J=new WeakSet,Y=(Q,V,H)=>{if(Z.length>=v7||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>=v7)return;let z=V?`${V}.${X}`:X;Z.push(z),Y(Q[X],z,H+1)}};return Y($,"",0),Z}function f7($){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>w7)return`${Q.slice(0,w7)}...<truncated ${Q.length-w7} 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>y7)return`${J.slice(0,y7)}...<truncated ${J.length-y7} chars>`;return J}function m0($,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=${b$(V)}`,`rootKeys=${a9(J)}`,`itemKeys=${a9(Q)}`,`payload=${f7(Z)}`].join(" "))}function h7($,Z,J){let Y=a(Z),Q=J_(Z),V=[`phase=${b$(J.phase??"event")}`,`method=${b$($)}`,`sourceMethod=${b$(J.sourceMethod)}`,`sourceType=${b$(J.sourceType)}`,`sessionId=${b$(J.sessionId)}`,`threadId=${b$(J.threadId)}`,`turnId=${b$(J.turnId)}`,`itemId=${b$(J.itemId)}`].join(" ");if(K(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${a9(Y)} itemKeys=${a9(Q)}`),K(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${Z_(Y_(Z))}`),Q)K(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${f7(Q)}`);K(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${f7(Z)}`)}function F4($){if(typeof $!=="string")return null;return $_.has($)?$:null}function Q_($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||nY.has(Z))return"end";return"event"}function I7($,Z){return aY($,a(Z)??{})}function g7($){let Z=a($);if(!Z)return null;let J=W0(Z.method)??W0(Z.type)??"raw_message";return aY(J,Z)}function aY($,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=F4(z.type),Q)break;if(!nY.has($)&&!Q)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),H=Q==="compacted"&&J?J:V&&F4(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:Q_(Q,$),sourceMethod:$,sourceType:Q??$}}var nY,$_,y7=200000,w7=50000,v7=400;var m7=O(()=>{f();nY=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),$_=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function U4($){return $!=null&&typeof $==="object"?$:null}function C$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function oY($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function o9($,Z){return $?C$($[Z]):void 0}function G2($){let Z=U4($);if(!Z)return null;let J=U4(Z.inputTokensDetails)??U4(Z.input_tokens_details),Y=U4(Z.outputTokensDetails)??U4(Z.output_tokens_details),Q={total_tokens:C$(Z.totalTokens??Z.total_tokens),input_tokens:C$(Z.inputTokens??Z.input_tokens),output_tokens:C$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:C$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??o9(Y,"reasoningTokens")??o9(Y,"reasoning_tokens")),cache_creation_input_tokens:C$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:C$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??o9(J,"cachedTokens")??o9(J,"cached_tokens"))};return oY(Q)?Q:null}function p7($,Z){let J=(Q)=>{let V=C$($?.[Q]),H=C$(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 oY(Y)?Y:null}function c7($){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 rY($){let Z=$.trim();if(Z.length<2)return Z;let J=r9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/''/g,"'");if(Z[0]==='"')return Y.replace(/\\"/g,'"');return Y}function l7($){let Z=H_(String($??"")),J=Z.split(`
71
+ `),U}let Z=H_($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${E0} is missing [feishu].app_id / [feishu].app_secret`);let Q=aY(Z.runtime?.projects_root??oY()),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[w,y]of Object.entries(S))if(typeof y==="string"&&y.length>0)C[w]=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 g={};for(let[x,I]of Object.entries(C)){if(typeof I!=="string"||I.length===0)continue;if(x.trim()==="model")g.model=I}U[y]=g}return U},P=()=>{let U={},S="projects.";for(let[C,w]of Object.entries(Z)){if(!C.startsWith("projects."))continue;let y=C.slice(9).trim();if(!y)continue;let g={};for(let[x,I]of Object.entries(w)){if(typeof I!=="string"||I.length===0)continue;switch(x.trim()){case"cwd":g.cwd=I;break;case"setting_sources":g.settingSources=I;break;case"strict_mcp":g.strictMcp=I==="true";break;case"tools":g.tools=I;break;case"load_project_mcp":g.loadProjectMcp=I==="true";break}}U[y]=g}return U},D=()=>{let U={},S="token_source.";for(let[C,w]of Object.entries(Z)){if(!C.startsWith("token_source."))continue;let y=C.slice(13).trim();if(!y)continue;let g={};for(let[x,I]of Object.entries(w)){if(typeof I!=="string")continue;let p=x.trim();if(p==="default")g.default=I==="true";else if(p==="agent"||p==="display"||p==="auth"||p==="base_url"||p==="auth_token"||p==="api_key"||p==="bin"||p==="model"||p==="effort"||p==="models"||p==="hidden_models"||p==="custom_models"||p==="slots"||p==="usage")g[p]=I}U[y]=g}return U},T=j("codex.env"),M=j("claude.env"),A=Z.claude?.bin?aY(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 rY(){h.token_sources=d9().token_sources}var h;var k0=O(()=>{V0();h=d9()});function W0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function x$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function i9($){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 W_($){let Z=$.slice(0,I7),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function G_($){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)??(D4(Z.type)?Z:null)??(J&&D4(J.type)?J:null)??(Y&&D4(Y.type)?Y:null)}function K_($){let Z=[],J=new WeakSet,Y=(Q,V,H)=>{if(Z.length>=I7||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>=I7)return;let z=V?`${V}.${X}`:X;Z.push(z),Y(Q[X],z,H+1)}};return Y($,"",0),Z}function g7($){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>h7)return`${Q.slice(0,h7)}...<truncated ${Q.length-h7} 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>f7)return`${J.slice(0,f7)}...<truncated ${J.length-f7} chars>`;return J}function g0($,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=${x$(V)}`,`rootKeys=${i9(J)}`,`itemKeys=${i9(Q)}`,`payload=${g7(Z)}`].join(" "))}function m7($,Z,J){let Y=a(Z),Q=G_(Z),V=[`phase=${x$(J.phase??"event")}`,`method=${x$($)}`,`sourceMethod=${x$(J.sourceMethod)}`,`sourceType=${x$(J.sourceType)}`,`sessionId=${x$(J.sessionId)}`,`threadId=${x$(J.threadId)}`,`turnId=${x$(J.turnId)}`,`itemId=${x$(J.itemId)}`].join(" ");if(K(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${i9(Y)} itemKeys=${i9(Q)}`),K(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${W_(K_(Z))}`),Q)K(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${g7(Q)}`);K(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${g7(Z)}`)}function D4($){if(typeof $!=="string")return null;return z_.has($)?$:null}function B_($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||sY.has(Z))return"end";return"event"}function p7($,Z){return tY($,a(Z)??{})}function c7($){let Z=a($);if(!Z)return null;let J=W0(Z.method)??W0(Z.type)??"raw_message";return tY(J,Z)}function tY($,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=D4(z.type),Q)break;if(!sY.has($)&&!Q)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),H=Q==="compacted"&&J?J:V&&D4(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:B_(Q,$),sourceMethod:$,sourceType:Q??$}}var sY,z_,f7=200000,h7=50000,I7=400;var u7=O(()=>{f();sY=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),z_=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function F4($){return $!=null&&typeof $==="object"?$:null}function S$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function eY($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function n9($,Z){return $?S$($[Z]):void 0}function H2($){let Z=F4($);if(!Z)return null;let J=F4(Z.inputTokensDetails)??F4(Z.input_tokens_details),Y=F4(Z.outputTokensDetails)??F4(Z.output_tokens_details),Q={total_tokens:S$(Z.totalTokens??Z.total_tokens),input_tokens:S$(Z.inputTokens??Z.input_tokens),output_tokens:S$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:S$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??n9(Y,"reasoningTokens")??n9(Y,"reasoning_tokens")),cache_creation_input_tokens:S$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:S$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??n9(J,"cachedTokens")??n9(J,"cached_tokens"))};return eY(Q)?Q:null}function l7($,Z){let J=(Q)=>{let V=S$($?.[Q]),H=S$(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 eY(Y)?Y:null}function d7($){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 $Q($){let Z=$.trim();if(Z.length<2)return Z;let J=a9[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 n7($){let Z=j_(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 K2($,Z=60){let{description:J,command:Y}=l7($);if(J)return J;return V_(Y).replace(/\s+/g," ").trim().slice(0,Z)}function V_($){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 H_($){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=z_(J[1]);return u7(Q||Z)}let Y=X_(Z);if(Y)return Y;return u7(Z)}function X_($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=rY(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 u7(rY(Q[2]));if(Y=Q[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function z_($){let Z=$.trim();if(Z.length<2)return Z;let J=r9[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/'\\''/g,"'");return Y.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
77
- `)}function u7($){let Z=$.trim(),J=Z[0];if(!r9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!W_(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 W_($,Z){let J=r9[Z];for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==='"'&&Q==="\\"&&Y+1<$.length){Y++;continue}if(Q===J)return/^[\s]*$/.test($.slice(Y+1))}return!1}var r9;var s9=O(()=>{r9={'"':'"',"'":"'","“":"”"}});function R($){return $ instanceof Error?$.message:String($)}function R0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function sY($,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 tY}from"node:path";function G_($){return $.kind==="fresh"?null:$.source.provider}function j0($,Z,J){let Y=G_($);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"||!tY($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!tY(J))throw Error(`expected conversation cwd is not absolute: ${J}`);if($.source.cwd===null)throw Error("conversation launch source cwd is missing");if($.source.cwd!==J)throw Error(`conversation launch cwd mismatch: source=${$.source.cwd} target=${J}`)}if($.kind!=="fork"||!$.through)return;if($.through.provider!==Z||$.through.source.provider!==Z)throw Error(`conversation checkpoint provider mismatch: checkpoint=${$.through.provider} target=${Z}`);if($.through.source.sessionId!==$.source.sessionId)throw Error("conversation checkpoint source does not match fork source");if($.through.source.cwd!==$.source.cwd)throw Error("conversation checkpoint cwd does not match fork source");if(!$.through.id.trim())throw Error("conversation checkpoint id is empty");if(Z==="dsh"&&(!/^\d+$/.test($.through.id)||!Number.isSafeInteger(Number($.through.id))))throw Error("DSH checkpoint must be a non-negative event sequence")}var A1=()=>{};import{createHash as K_,randomUUID as eY}from"node:crypto";import{existsSync as t9,lstatSync as e9,mkdirSync as d7,readFileSync as $Q,readdirSync as B_,realpathSync as B2,rmSync as __,symlinkSync as j_,writeFileSync as L_}from"node:fs";import{homedir as q_}from"node:os";import{isAbsolute as P_,join as k$,relative as D_,resolve as F_,sep as U_}from"node:path";class ZQ{defaultHome;root;stateFile;constructor($=F_(process.env.CODEX_HOME||k$(q_(),".codex")),Z=dJ,J=iJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!t9(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse($Q(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!==u&&!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:u,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(u);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(u);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:eY(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),s(this.stateFile,Z),Y}remove($){let Z=this.get($);if($===u)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(Z8($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(J8($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Y=this.home($),Q;try{Q=e9(Y)}catch(H){if(H.code!=="ENOENT")throw H}if(Q){if(Q.isSymbolicLink()||!Q.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(t9(this.defaultHome)){let H=D_(B2(Y),B2(this.defaultHome));if(!H||!P_(H)&&H!==".."&&!H.startsWith(`..${U_}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{__(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[$]:u}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($!==u){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:eY()}),s(this.stateFile,J)}}home($=u){return $===u?this.defaultHome:k$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===u)return Z;let J;try{J=e9(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(d7(Z,{recursive:!0,mode:448}),d7(this.defaultHome,{recursive:!0,mode:448}),B2(Z)===B2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=e9(k$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{L_(k$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of M_){let H=k$(this.defaultHome,V);d7(H,{recursive:!0,mode:448}),this.link(H,k$(Z,V),!0)}let Q=new Set([...A_,...B_(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Q){let H=k$(this.defaultHome,V);if(t9(H))this.link(H,k$(Z,V),!1)}return Z}link($,Z,J){let Y;try{Y=e9(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||B2(Z)!==B2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}j_($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&Z8($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Q};if($!==u){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($),$===u?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=k$(this.home($),"auth.json");if(!t9(Z))return null;let Y=JSON.parse($Q(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 K_("sha256").update(JSON.stringify([Y.account_id,V.sub])).digest("hex")}}function o$($,Z,J=!0){if(JQ.set($,Z),!$8.has($))$.once("exit",()=>$8.delete($));$8.set($,{id:Z,ownsNativeProcess:J})}function J8($,Z=!1){return[...$8].some(([J,Y])=>Y.id===$&&(Y.ownsNativeProcess||Z)&&J.isAlive())}function Z8($){return M4.has($)}function YQ($){if(M4.has($))throw Error("该账号已有登录任务");if(J8($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return M4.set($,Z),()=>{if(M4.get($)===Z)M4.delete($)}}function r0($){return $?JQ.get($)??u:u}var u="default",M_,A_,k,JQ,$8,M4;var p0=O(()=>{V0();S0();M_=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],A_=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];k=new ZQ,JQ=new WeakMap,$8=new Map;M4=new Map});function i7($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function O_($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function A4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:i7($.subscriptionType,J.fiveHour)}}function n7($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=A4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function a7($,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=O_($.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=A4($,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 Y8($){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 R_,existsSync as N_,mkdirSync as T_,openSync as E_,readdirSync as x_,readSync as S_,statSync as V8,writeFileSync as b_}from"node:fs";import{homedir as o7}from"node:os";import{delimiter as QQ,isAbsolute as VQ,join as r$}from"node:path";import{EventEmitter as C_}from"node:events";import{StringDecoder as HQ}from"node:string_decoder";import{spawn as k_}from"cross-spawn";function O4(){return _4("codex","codex")}function y_(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([r$(o7(),".local","npm-global","bin"),r$(o7(),".local","bin"),r$(o7(),".bun","bin"),...(process.env.PATH??"").split(QQ),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(QQ)}function zQ($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function m_($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function p_($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function s0($){return typeof $==="string"&&t7.includes($)}function c_($){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(!s0(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 r7($,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:s7($)}}return null}function u_($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function s7($){return{status:$.status,revisedPrompt:u_($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function WQ($){if(!$||!N_(XQ))return null;let Z=null,J=[XQ];while(J.length){let Y=J.pop(),Q;try{Q=x_(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=r$(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=V8(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 _Q($,Z,J=w_){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let V=l_($,Z,J);if(V)return V;if(Q.length>2048){let H=jQ($);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 l_($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=d_(Y);if(!Q)return null;let V=GQ(Z??"unknown-thread"),H=GQ(jQ($)),X=r$(J,V),z=r$(X,`${H}.${Q.ext}`);try{return T_(X,{recursive:!0}),b_(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 jQ($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function GQ($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function d_($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=n_(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=i_(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function i_($){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 n_($){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 KQ($,Z,J){let Y=r7($,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:_Q($,J),isError:$.status==="failed"}}return null}function Q8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return R0(Z)}function BQ($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function a_($,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 K2(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 LQ($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function o_($){let Z=LQ($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function r_($){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(`${R0(Y)}: ${H}`)}return J.join(`
79
- `)}var XQ,w_,v_=30000,f_=600000,h_=5000,I_=60000,g_="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",t7,R4="xhigh",_2,j2;var O1=O(()=>{y0();f();H2();m7();s9();A1();q4();p0();m7();XQ=r$(k.defaultHome,"sessions"),w_=r$(k.defaultHome,"generated_images");t7=["none","minimal","low","medium","high","xhigh","max","ultra"];_2=class _2 extends Error{method;requestId;serverCode;serverMessage;serverData;constructor($,Z,J,Y,Q){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Y}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Y;this.serverData=Q;this.name="CodexRpcResponseError"}};j2=class j2 extends C_{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 HQ("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=O4(),J=[...m_($.allowDelegation!==!1),...k.cliArgs($.codexAccountId??u)];K(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:y_(),...h.codex.env,...$.hostEnv??{}},Q=k.env($.codexAccountId??u,$.transformEnv?$.transformEnv(Y):Y);this.proc=k_(Z,J,p_($.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)),o$(this,$.codexAccountId??u)}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 X2($,Z=60){let{description:J,command:Y}=n7($);if(J)return J;return __(Y).replace(/\s+/g," ").trim().slice(0,Z)}function __($){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 j_($){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=q_(J[1]);return i7(Q||Z)}let Y=L_(Z);if(Y)return Y;return i7(Z)}function L_($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=$Q(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 i7($Q(Q[2]));if(Y=Q[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function q_($){let Z=$.trim();if(Z.length<2)return Z;let J=a9[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 i7($){let Z=$.trim(),J=Z[0];if(!a9[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!P_(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 P_($,Z){let J=a9[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 a9;var o9=O(()=>{a9={'"':'"',"'":"'","“":"”"}});function N($){return $ instanceof Error?$.message:String($)}function O0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function ZQ($,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 JQ}from"node:path";function D_($){return $.kind==="fresh"?null:$.source.provider}function _0($,Z,J){let Y=D_($);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"||!JQ($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!JQ(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 D1=()=>{};import{createHash as F_,randomUUID as YQ}from"node:crypto";import{existsSync as r9,lstatSync as s9,mkdirSync as a7,readFileSync as QQ,readdirSync as M_,realpathSync as z2,rmSync as U_,symlinkSync as A_,writeFileSync as O_}from"node:fs";import{homedir as R_}from"node:os";import{isAbsolute as N_,join as C$,relative as T_,resolve as E_,sep as x_}from"node:path";class VQ{defaultHome;root;stateFile;constructor($=E_(process.env.CODEX_HOME||C$(R_(),".codex")),Z=oJ,J=rJ){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!r9(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(QQ(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!==u&&!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:u,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(u);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(u);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:YQ(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),s(this.stateFile,Z),Y}remove($){let Z=this.get($);if($===u)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(e9($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if($8($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Y=this.home($),Q;try{Q=s9(Y)}catch(H){if(H.code!=="ENOENT")throw H}if(Q){if(Q.isSymbolicLink()||!Q.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(r9(this.defaultHome)){let H=T_(z2(Y),z2(this.defaultHome));if(!H||!N_(H)&&H!==".."&&!H.startsWith(`..${x_}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{U_(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[$]:u}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($!==u){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:YQ()}),s(this.stateFile,J)}}home($=u){return $===u?this.defaultHome:C$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===u)return Z;let J;try{J=s9(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(a7(Z,{recursive:!0,mode:448}),a7(this.defaultHome,{recursive:!0,mode:448}),z2(Z)===z2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=s9(C$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{O_(C$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of S_){let H=C$(this.defaultHome,V);a7(H,{recursive:!0,mode:448}),this.link(H,C$(Z,V),!0)}let Q=new Set([...C_,...M_(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Q){let H=C$(this.defaultHome,V);if(r9(H))this.link(H,C$(Z,V),!1)}return Z}link($,Z,J){let Y;try{Y=s9(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||z2(Z)!==z2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}A_($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&e9($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Q};if($!==u){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($),$===u?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=C$(this.home($),"auth.json");if(!r9(Z))return null;let Y=JSON.parse(QQ(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 F_("sha256").update(JSON.stringify([Y.account_id,V.sub])).digest("hex")}}function i$($,Z,J=!0){if(HQ.set($,Z),!t9.has($))$.once("exit",()=>t9.delete($));t9.set($,{id:Z,ownsNativeProcess:J})}function $8($,Z=!1){return[...t9].some(([J,Y])=>Y.id===$&&(Y.ownsNativeProcess||Z)&&J.isAlive())}function e9($){return M4.has($)}function XQ($){if(M4.has($))throw Error("该账号已有登录任务");if($8($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return M4.set($,Z),()=>{if(M4.get($)===Z)M4.delete($)}}function a0($){return $?HQ.get($)??u:u}var u="default",S_,C_,k,HQ,t9,M4;var m0=O(()=>{V0();x0();S_=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],C_=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];k=new VQ,HQ=new WeakMap,t9=new Map;M4=new Map});function o7($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function b_($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function U4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:o7($.subscriptionType,J.fiveHour)}}function r7($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=U4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function s7($,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=b_($.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=U4($,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 Z8($){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 k_,existsSync as y_,mkdirSync as v_,openSync as w_,readdirSync as f_,readSync as h_,statSync as Y8,writeFileSync as I_}from"node:fs";import{homedir as t7}from"node:os";import{delimiter as zQ,isAbsolute as WQ,join as n$}from"node:path";import{EventEmitter as g_}from"node:events";import{StringDecoder as GQ}from"node:string_decoder";import{spawn as m_}from"cross-spawn";function A4(){return B4("codex","codex")}function p_(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([n$(t7(),".local","npm-global","bin"),n$(t7(),".local","bin"),n$(t7(),".bun","bin"),...(process.env.PATH??"").split(zQ),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(zQ)}function BQ($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function a_($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function o_($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function o0($){return typeof $==="string"&&Z3.includes($)}function r_($){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(!o0(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 e7($,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:$3($)}}return null}function s_($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function $3($){return{status:$.status,revisedPrompt:s_($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function _Q($){if(!$||!y_(KQ))return null;let Z=null,J=[KQ];while(J.length){let Y=J.pop(),Q;try{Q=f_(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=n$(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=Y8(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 PQ($,Z,J=c_){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let V=t_($,Z,J);if(V)return V;if(Q.length>2048){let H=DQ($);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 t_($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=e_(Y);if(!Q)return null;let V=jQ(Z??"unknown-thread"),H=jQ(DQ($)),X=n$(J,V),z=n$(X,`${H}.${Q.ext}`);try{return v_(X,{recursive:!0}),I_(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 DQ($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function jQ($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function e_($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=Zj(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=$j(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function $j($){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 Zj($){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 LQ($,Z,J){let Y=e7($,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:PQ($,J),isError:$.status==="failed"}}return null}function J8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return O0(Z)}function qQ($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function Jj($,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 X2(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 FQ($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function Yj($){let Z=FQ($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function Qj($){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(`${O0(Y)}: ${H}`)}return J.join(`
79
+ `)}var KQ,c_,u_=30000,l_=600000,d_=5000,i_=60000,n_="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",Z3,O4="xhigh",W2,G2;var F1=O(()=>{k0();f();J2();u7();o9();D1();L4();m0();u7();KQ=n$(k.defaultHome,"sessions"),c_=n$(k.defaultHome,"generated_images");Z3=["none","minimal","low","medium","high","xhigh","max","ultra"];W2=class W2 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"}};G2=class G2 extends g_{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 GQ("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=A4(),J=[...a_($.allowDelegation!==!1),...k.cliArgs($.codexAccountId??u)];K(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:p_(),...h.codex.env,...$.hostEnv??{}},Q=k.env($.codexAccountId??u,$.transformEnv?$.transformEnv(Y):Y);this.proc=m_(Z,J,o_($.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)),i$(this,$.codexAccountId??u)}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 _2(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=g7($);if(Z){let J=this.withSessionId(Z);h7(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}m0("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=I7($,Z);if(J){let Y=this.withSessionId(J);h7($,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(s0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=G2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else K("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=G2(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){m0("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){m0("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 m0("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&&zQ(H?.message)&&this.scheduleCapacityRetry(H.message,g_))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&&Y8(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 m0("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}}m0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){m0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=r7(Z,this.opts.workDir);if(!J){m0("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){m0("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=KQ(Z,this.opts.workDir,this.sessionId??void 0);if(!J){m0("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:s7(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)??R0(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"?r7($,this.opts.workDir):KQ($,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:a_(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=Q8($.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=Q8($.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=LQ($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,Q8(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:BQ($.prompt),description:o_($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:r_($),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($)??Q8(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:BQ(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 HQ("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=WQ(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=V8($).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??WQ(this.sessionId);if(!$){K(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=V8($).size;if(Q<=this.rolloutReadOffset)return;let V=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let H=E_($,"r"),X=0;try{while(X<V){let z=S_(H,Z,X,V-X,this.rolloutReadOffset+X);if(z===0)break;X+=z}}finally{R_(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=_Q($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&VQ(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:s7({...$,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:m0("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||!VQ(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(s0(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},f_))?.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=V8(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(j0($,"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 W2(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=c7($);if(Z){let J=this.withSessionId(Z);m7(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}g0("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=p7($,Z);if(J){let Y=this.withSessionId(J);m7($,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(o0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=H2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else K("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=H2(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){g0("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){g0("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 g0("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&&BQ(H?.message)&&this.scheduleCapacityRetry(H.message,n_))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&&Z8(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 g0("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}}g0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){g0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=e7(Z,this.opts.workDir);if(!J){g0("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){g0("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=LQ(Z,this.opts.workDir,this.sessionId??void 0);if(!J){g0("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:$3(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)??O0(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"?e7($,this.opts.workDir):LQ($,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:Jj(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=J8($.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=J8($.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=FQ($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,J8(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:qQ($.prompt),description:Yj($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:Qj($),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($)??J8(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:qQ(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 GQ("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=_Q(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=Y8($).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??_Q(this.sessionId);if(!$){K(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=Y8($).size;if(Q<=this.rolloutReadOffset)return;let V=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let H=w_($,"r"),X=0;try{while(X<V){let z=h_(H,Z,X,V-X,this.rolloutReadOffset+X);if(z===0)break;X+=z}}finally{k_(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=PQ($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&WQ(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:$3({...$,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:g0("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=u_){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||!WQ(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(o0(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},l_))?.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=Y8(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:c_(Y.supportedReasoningEfforts),defaultReasoningEffort:s0(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(X2("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 _2&&$.method==="turn/start"&&zQ($.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 _2&&$.method==="turn/start"&&Z.inputText!==void 0&&(Y8($.serverData)||Y8({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(h_*2**Math.min(J-1,4),I_),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:m0("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 s_($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function e7($){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})${s_(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 $3($,Z){if(!$)return $;let J=e7($);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 t_($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function qQ($){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 s$($){if(Array.isArray($))return $.map((Y)=>s$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=s$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=Z3(Z.content);return J}function Z0($){return $3($,(Z)=>e_(qQ(t_(Z))))}function e_($){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:r_(Y.supportedReasoningEfforts),defaultReasoningEffort:o0(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(Y2("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 W2&&$.method==="turn/start"&&BQ($.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 W2&&$.method==="turn/start"&&Z.inputText!==void 0&&(Z8($.serverData)||Z8({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(d_*2**Math.min(J-1,4),i_),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:g0("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 Vj($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function J3($){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})${Vj(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 Y3($,Z){if(!$)return $;let J=J3($);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 Hj($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function MQ($){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 a$($){if(Array.isArray($))return $.map((Y)=>a$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=a$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=Q3(Z.content);return J}function Z0($){return Y3($,(Z)=>Xj(MQ(Hj(Z))))}function Xj($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
87
87
  \`\`\`
88
88
  ${J.trim()}
89
89
  \`\`\`
@@ -91,194 +91,196 @@ ${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 Z3($){return $3($,qQ)}var N;var b0=O(()=>{N={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",fileDeliveryList:"file_delivery_list",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 PQ($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function $j($,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 DQ($){return $==="workflow"||$==="monitor"}function t0($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function R1($){return $.some((Z)=>!t0(Z))}function Q3($,Z,J=Date.now()){let Y=$j(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:[],...DQ(Y)?{isBackgrounded:!0}:{}};return DQ(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function V3($,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 H3($,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 X3($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function z3($,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 H8($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>Zj){J=Y+1;break}return J===0?$:$.slice(J)}function Jj($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return K2(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 Yj($,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 W3($,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:H8([...W.steps,{toolUseId:J,tool:Y,brief:`${Y} ${Jj(Y,Q)}`.trim()}])}:W);return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function G3($,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:H8([...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:H8(_)}});return{active:H?z($.active):$.active,pending:X?z($.pending):$.pending}}function K3($,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} → ${Yj(Y,Q)}`}});return{...W,steps:H8(B)}});return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function MQ($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of Hj)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 t$($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=J3){let Y=Math.floor((J-J3)/FQ),Q=J3+(Y+1)*FQ;return{label:`${G0((10+Y*5)*60,"down")}+`,nextDelayMs:Q-J}}return{label:G0(Math.floor(J/1000)),nextDelayMs:UQ}}return MQ($)}function Xj($){return $.subagentType??$.workflowName??Vj[$.type]}function Y3($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function zj($,Z,J="bucket"){let Y=(Q)=>t$(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(Y3($)/1000)}`;case"failed":return`❌ 失败 ${G0(Y3($)/1000)}`;case"killed":return`\uD83D\uDC80 已终止 ${G0(Y3($)/1000)}`}}function AQ($){let Z=$.filter((Y)=>!t0(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function X8($){return`\uD83E\uDDED 后台任务 · ${AQ($)}`}function Wj($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(t0($)&&$.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 Z0(Z.length>0?Z.join(`
96
- `):"_(暂无执行记录)_")}function L2($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:N4.panel($.id),header:{title:{tag:"plain_text",content:`${Qj[$.type]} ${Xj($)} · ${$.description||"(无描述)"} — ${zj($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:N4.body($.id),content:Wj($)}]}}function B3($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:X8($)}},body:{elements:$.map((Y)=>L2(Y,Z,J))}}}function z8($,Z=Date.now(),J="bucket"){let Y=$.filter(t0);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>L2(Q,Z,J))}}}function _3(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var N4,Zj=1000,Qj,Vj,Hj,UQ=1000,J3=600000,FQ=300000;var j3=O(()=>{b0();s9();N4={panel:($)=>`bg_${PQ($)}`,body:($)=>`bgb_${PQ($)}`};Qj={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},Vj={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"},Hj=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as Gj}from"node:events";import{join as Kj,isAbsolute as Bj,extname as _j,basename as jj}from"node:path";import{readFile as Lj}from"node:fs/promises";function qj($){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 W8=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),L3,q3;var OQ=O(()=>{_0();A1();D4();f();L3={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};q3=class q3 extends Gj{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=W8();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"};j0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new i9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:Kj($.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(L3).find((Y)=>L3[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)=>!Bj(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(_j(V).toLowerCase()))continue;let H=await Lj(V);J.push({type:"image",mediaType:qj(H),name:jj(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 M1}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={...W8(),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=W8(),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=L3[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={...W8(),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 e$($){return $.startsWith("claude:")?$:`claude:${$}`}function P3($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(h.claude.models,Z))return h.claude.models[Z]?.model?.trim()||"opus";return Z}var RQ=O(()=>{y0()});import{existsSync as Pj,readFileSync as Dj}from"node:fs";function D3(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:aJ}function E4(){if(T4!==null)return T4;try{T4=Pj(D3())?JSON.parse(Dj(D3(),"utf8")):{}}catch($){K(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),T4={}}return T4??{}}function Uj(){try{s(D3(),E4())}catch($){K(`context-window-observe: cache write MISS (${$?.message??$})`)}}function F3($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function NQ($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=F3($,Z),Q=E4()[Y];if(Q===J)return;E4()[Y]=J,Uj(),K(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function G8($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=E4()[F3($,Z)];return J!=null&&J<Fj?Z:`${Z}[1m]`}function q2($,Z){return E4()[F3($,Z)]}var Fj=1e6,T4=null;var x4=O(()=>{V0();f();S0()});var pQ={};E$(pQ,{toolsFromProfile:()=>gQ,settingSourcesFromProfile:()=>IQ,resolveClaudeExecutableConfig:()=>R3,resetClaudeContextWindowCache:()=>Tj,readProjectMcpServers:()=>mQ,readLastCallUsageFromTranscript:()=>vQ,claudeTranscriptPath:()=>j8,claudeTranscriptDir:()=>_8,claudeManagedSkillOptions:()=>yQ,buildClaudeSpawnPath:()=>wQ,assertClaudeCodeAvailable:()=>O3,ClaudeAgentProcess:()=>L8,CLAUDE_PERMISSION_MODE:()=>hQ});import{existsSync as bQ,readFileSync as CQ}from"node:fs";import{homedir as B8}from"node:os";import{spawn as Mj}from"cross-spawn";import{delimiter as TQ,join as N1}from"node:path";import{EventEmitter as Aj}from"node:events";function yQ($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function Oj($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function Rj($){let Z=Mj($.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 O3(){R3(),M7("claude","@anthropic-ai/claude-agent-sdk")}function R3($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?h.claude.bin:$.configuredBin;if(J){if(!($.exists??bQ)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&Oj(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:Rj,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function wQ(){if(process.platform==="win32")return process.env.PATH??"";let $=[N1(B8(),".local","npm-global","bin"),N1(B8(),".local","bin"),N1(B8(),".bun","bin"),...(process.env.PATH??"").split(TQ),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(TQ)}function Nj($){let Z=G2($);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 EQ($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function _8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||N1(B8(),".claude");return N1(J,"projects",Z)}function j8($,Z){return N1(_8($),`${Z}.jsonl`)}function vQ($){let Z;try{Z=CQ($,"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 xQ($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function Tj(){M3.clear()}function Ej($){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)+P2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+P2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+P2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+P2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+P2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let H=P2(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 K8($){return{...$}}function U3($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function xj($,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 P2($){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 Sj($){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 bj($){return`server_tool:${$}`}function Cj($){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 kj($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function yj($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[a$];return{id:e$($.value),model:e$($.value),displayName:$.displayName||e$($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(a$)?a$:Z[0]}}function IQ($){if(!$?.settingSources)return[...SQ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...SQ]}function gQ($){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 mQ($){let Z=N1($,".mcp.json"),J;try{J=CQ(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 wj($){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=A3(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=fj(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 fj($){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=A3(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let V=A3(Y.description,Y.detail,Y.preview);Z.push(V?{label:Q,description:V}:{label:Q})}return Z}function A3(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var kQ,M3,hQ="default",SQ,L8;var S4=O(()=>{H2();y0();f();_0();RQ();x4();kQ=class kQ{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($))}};M3=new Map;SQ=["project","local"];L8=class L8 extends Aj{provider="claude";tokenSourceId;opts;input=new kQ;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;queryStart;initializationError=null;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?e$($.model):null}sendInitialize(){if(this.started)return;this.started=!0,this.queryStart=this.initializeQuery().catch(($)=>{if(this.initializationError=$ instanceof Error?$:Error(String($)),this.emit("error",this.initializationError),!this.query)this.finishExit(1,null)})}async*validatedInput(){if(await this.queryStart,this.initializationError||!this.alive)return;yield*this.input}async initializeQuery(){let $=P3(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??IQ(Z),Y=yQ(J,this.opts.managedSkillPluginPath),Q=gQ(Z),V=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?mQ(this.opts.workDir):void 0;try{let X=R3(),{query:z}=await MY();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:wQ(),...h.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.opts.validateAccount?this.validatedInput():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:hQ,env:G,settingSources:[...J],...this.opts.settings?{settings:this.opts.settings}:{},...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.initializationError=z,this.emit("error",z),this.finishExit(1,null);return}if(this.readLoop(this.query),this.opts.validateAccount)try{this.opts.validateAccount(await this.query.accountInfo())}catch(X){this.initializationError=X instanceof Error?X:Error(String(X)),this.emit("error",this.initializationError),await this.kill()}}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.initializationError)throw this.initializationError;if(!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=P3($);if(!U0(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.initializationError)throw this.initializationError;if(!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?e$($):"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 M1)},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=wj(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=e$($.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=e$(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=Cj(Q.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(kj(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,bj(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,Sj(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=Nj($.usage),J=$.modelUsage??$.model_usage,Y=Ej(J);if(!Z&&!Y.usage)K(`claude-agent-process: result usage missing rootKeys=${U3($).join(",")||"-"} usageKeys=${U3($.usage).join(",")||"-"} modelUsageKeys=${U3(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=K8(Y.usage),this.lastTotalUsage=K8(Y.usage);else if(Z)this.cumulativeUsageFromResults=xj(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=K8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?K8(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=xQ(this.opts.model,this.tokenSourceId);if(M3.set(X,Y.contextWindow),this.tokenSourceId)for(let[z,W]of Object.entries(J??{})){let G=W?.contextWindow;if(typeof G==="number"&&G>0)NQ(this.tokenSourceId,z,G)}}this.lastContextWindow=M3.get(xQ(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=j8(this.opts.workDir,this.sessionId??""),V=vQ(Q);if(this.lastContextTokens=EQ(V)??(bQ(Q)?EQ(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 dQ={};E$(dQ,{waitForTokenSourceModelRefresh:()=>O2,tokenSourceRuntimeModels:()=>F2,tokenSourceRuntimeModel:()=>L$,tokenSourceProcessRevision:()=>U2,tokenSourceFactories:()=>M2,setDefaultTokenSource:()=>T3,scrubDshEnv:()=>b4,scrubAnthropicEnv:()=>e0,resetTokenSourceRegistry:()=>E3,registerTokenSourceFactory:()=>M0,registerTokenSource:()=>N3,refreshAllTokenSourceModels:()=>k4,pendingTokenSourceModelRefresh:()=>A2,listTokenSourcesByAgent:()=>lQ,listTokenSources:()=>y$,listEnabledTokenSourcesByAgent:()=>D8,getTokenSourceForAccount:()=>H0,getTokenSource:()=>q$,ANTHROPIC_ENV_KEYS:()=>P8});function e0($){let Z={...$};for(let J of P8)delete Z[J];return Z}function b4($){let Z=e0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function F2($){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 F2($).find((Y)=>J(Y.model)===J(Z))}function U2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function M0($){cQ.set($.kind,$)}function M2(){return[...cQ.values()]}function N3($,Z){if(C4.set($.id,$),Z?.default||q8===null)q8=$.id}function q$($){return $?C4.get($):void 0}function H0($,Z="default"){let J=q$($);return J?.forAccount?J.forAccount(Z):J}function y$(){return[...C4.values()]}function lQ($){return y$().filter((Z)=>Z.agent===$)}function D8($){return lQ($).filter((Z)=>Z.enabled)}function T3($){if(C4.has($))q8=$}function E3(){C4.clear(),q8=null,uQ++}function k4(){let $=uQ;if(D2?.generation===$)return D2.promise;let Z=Promise.allSettled(y$().map(async(J)=>{await J.refreshModels(),K(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(D2?.promise===Z)D2=null});return D2={generation:$,promise:Z},Z}function A2(){return D2?.promise??null}async function O2(){let $;while($=A2())await $}var P8,cQ,C4,q8=null,uQ=0,D2=null;var Y0=O(()=>{f();P8=["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"];cQ=new Map;C4=new Map});import{spawn as hj}from"cross-spawn";import{EventEmitter as Ij}from"node:events";import{StringDecoder as gj}from"node:string_decoder";import{createHash as mj}from"node:crypto";function S3($,Z){if(v4.set($,Z),Z.state==="ok")U8.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")U8.delete($)}function nQ($,Z,J=(Y)=>new T1({accountId:Y})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Y=F8.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 订阅,不能使用重置卡");R2($);let W;try{W=await A8(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{R2($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(W?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(W)};请用 codex-accounts 核对后再操作`);let G=P$.get($),B;try{B=b3(await A8(()=>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 S3($,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(F8.get($)?.promise===Q)F8.delete($)});return F8.set($,{key:Z,promise:Q}),Q}function aQ($,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 pj($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function M8($){if(!$)return null;return{percent:pj($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function cj($){let Z=M8($?.primary),J=M8($?.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 uj($){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}=cj(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 oQ($,Z=u){let J=lj($),Y=v4.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],V=Q.filter((H)=>iQ(H.fiveHour,M8($?.primary))&&iQ(H.weekly,M8($?.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 iQ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function dj($){let Z=new T1({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await aQ(Z.request("account/read",{}),x3))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await A8(()=>Z.request("account/rateLimits/read",{}));return b3(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 b3($,Z){let{buckets:J,defaultLimitId:Y}=uj($),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=i7(V,Q.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:mj("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 rQ($=u){return v4.get($)??null}function sQ($=u){return U8.get($)??null}function E1($=u){let Z=y4.get($);if(Z)return Z;let J=P$.get($)??0,Y=Promise.resolve().then(()=>dj($)).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 S3($,Q),Q}).finally(()=>{if(y4.get($)===Y)y4.delete($)});return y4.set($,Y),Y}function O8($,Z=u){let J=w4.get(Z);if(J)return J;let Y=P$.get(Z)??0,Q=A8(()=>$("account/rateLimits/read",{})).then((V)=>{if((P$.get(Z)??0)!==Y)return null;let H=b3(V);if((P$.get(Z)??0)===Y)S3(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)v4.delete(Z);return null}).finally(()=>{if(w4.get(Z)===Q)w4.delete(Z)});return w4.set(Z,Q),Q}function R2($){P$.set($,(P$.get($)??0)+1),v4.delete($),U8.delete($),y4.delete($),w4.delete($)}async function A8($,Z="额度查询"){let J=[1000,4000];for(let Y=0;;Y++)try{return await aQ($(),x3)}catch(Q){let V=Q instanceof Error?Q.message:String(Q);if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(V))throw Q;if(Y>=J.length)throw Error(`Codex ${Z}失败(已尝试 ${Y+1} 次):${V}`,{cause:Q});K(`usage: ${Z} retry ${Y+1}/${J.length} in ${J[Y]}ms: ${V}`),await new Promise((X)=>setTimeout(X,J[Y]))}}var x3=1e4,v4,U8,y4,F8,T1,w4,P$;var w$=O(()=>{O1();f();y0();p0();v4=new Map,U8=new Map,y4=new Map;F8=new Map;T1=class T1 extends Ij{proc;buf="";decoder=new gj("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??u;this.proc=hj($.bin??O4(),["app-server","--listen","stdio://",...$.args??k.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??k.env(Z,{...process.env,...h.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}`))}),o$(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 Q3($){return Y3($,MQ)}var R;var S0=O(()=>{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",fileDeliveryList:"file_delivery_list",agentIdentityPanel:"agent_id_panel",agentRunFooter:"agent_run_footer"}});function F0($,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 UQ($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function zj($,Z){let J=$??"";if(J==="agent"||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 AQ($){return $==="workflow"||$==="monitor"}function Q$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function X3($){return $.some((Z)=>!Q$(Z))}function N4($,Z,J=Date.now()){let Y=zj(Z.task_type,Z.subagent_type),Q=(z)=>z.id===Z.task_id||!!Z.tool_use_id&&z.toolUseId===Z.tool_use_id,V=$.active.some(Q),H=$.pending.some(Q);if(V||H){let z=(W)=>({...W,...Q$(W)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type:Y==="unknown"?W.type:Y,toolUseId:Z.tool_use_id??W.toolUseId,description:Z.description||W.description,subagentType:Z.subagent_type??W.subagentType,workflowName:Z.workflow_name??W.workflowName,prompt:Z.prompt??W.prompt});if(H&&Y==="subagent")return{active:[...$.active,...$.pending.filter(Q).map(z)],pending:$.pending.filter((W)=>!Q(W))};return{active:V?$.active.map((W)=>Q(W)?z(W):W):$.active,pending:H?$.pending.map((W)=>Q(W)?z(W):W):$.pending}}let X={id:Z.task_id,displayId:Z.tool_use_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:[],...AQ(Y)?{isBackgrounded:!0}:{}};return Y==="subagent"||AQ(Y)?{active:[...$.active,X],pending:$.pending}:{active:$.active,pending:[...$.pending,X]}}function z3($,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 W3($,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 G3($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function V8($,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 Q8($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>Wj){J=Y+1;break}return J===0?$:$.slice(J)}function Gj($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return X2(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 Kj($,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 K3($,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:Q8([...W.steps,{toolUseId:J,tool:Y,brief:`${Y} ${Gj(Y,Q)}`.trim()}])}:W);return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function B3($,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:Q8([...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:Q8(_)}});return{active:H?z($.active):$.active,pending:X?z($.pending):$.pending}}function _3($,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} → ${Kj(Y,Q)}`}});return{...W,steps:Q8(B)}});return{active:V?X($.active):$.active,pending:H?X($.pending):$.pending}}function EQ($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of Bj)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:`${F0((Y+1)*600,"down")}+`,nextDelayMs:Q-Z}}function K2($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=V3){let Y=Math.floor((J-V3)/OQ),Q=V3+(Y+1)*OQ;return{label:`${F0((10+Y*5)*60,"down")}+`,nextDelayMs:Q-J}}return{label:F0(Math.floor(J/1000)),nextDelayMs:TQ}}return EQ($)}function RQ($){return $.subagentType??$.workflowName??H3[$.type]}function _j($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function jj($){let Z=[`**${H3[$.type]}**${RQ($)!==H3[$.type]?` · ${RQ($)}`:""}${Q$($)?` · 用时 ${F0(_j($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Z.push(`⚠ ${$.error}`);if($.summary)Z.push("",`**${Q$($)?"结果":"进度"}**`,NQ($.summary,8000));if($.prompt)Z.push("","**任务说明**",NQ($.prompt,2000));if($.steps.length){Z.push("","**最近动作**");for(let J of $.steps.slice(-3))Z.push(`- ${J.brief}`)}else if($.lastToolName)Z.push("",`最近动作:${$.lastToolName}`);return Z0(Z.join(`
96
+ `))}function NQ($,Z){return $.length<=Z?$:`${$.slice(0,Z)}
97
+ _这里只显示预览。_`}function H8($){let Z={running:"⏳ 正在执行",pending:"⏳ 等待执行",paused:"⏸️ 已暂停",completed:"✅ 委派完成",failed:"❌ 委派失败",killed:"\uD83D\uDED1 委派已终止"}[$.status],J=$.description.replace(/\s+/g," ").trim()||"说明 MISS";return`${Z} · ${J.length<=40?J:`${J.slice(0,39)}…`}`}function j3($){return{tag:"collapsible_panel",element_id:R4.panel($.id),header:{title:{tag:"plain_text",content:H8($)}},expanded:!1,elements:[{tag:"markdown",element_id:R4.body($.id),content:jj($)}]}}var R4,Wj=1000,H3,Bj,TQ=1000,V3=600000,OQ=300000;var L3=O(()=>{S0();o9();R4={panel:($)=>`bg_${UQ($)}`,body:($)=>`bgb_${UQ($)}`};H3={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"},Bj=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as Lj}from"node:events";import{join as qj,isAbsolute as Pj,extname as Dj,basename as Fj}from"node:path";import{readFile as Mj}from"node:fs/promises";function Uj($){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 X8=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),q3,P3;var xQ=O(()=>{B0();D1();P4();f();q3={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};P3=class P3 extends Lj{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=X8();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 l9({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:qj($.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(q3).find((Y)=>q3[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)=>!Pj(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(`
98
+ `)}],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(Dj(V).toLowerCase()))continue;let H=await Mj(V);J.push({type:"image",mediaType:Uj(H),name:Fj(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(!K0(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 P1}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={...X8(),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}
99
+
100
+ ${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=X8(),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=q3[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={...X8(),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 T4($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(h.claude.models,Z))return h.claude.models[Z]?.model?.trim()||"opus";return Z}var D3=O(()=>{k0()});import{existsSync as Aj,readFileSync as Oj}from"node:fs";function F3(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:tJ}function x4(){if(E4!==null)return E4;try{E4=Aj(F3())?JSON.parse(Oj(F3(),"utf8")):{}}catch($){K(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),E4={}}return E4??{}}function Nj(){try{s(F3(),x4())}catch($){K(`context-window-observe: cache write MISS (${$?.message??$})`)}}function M3($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function SQ($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=M3($,Z),Q=x4()[Y];if(Q===J)return;x4()[Y]=J,Nj(),K(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function z8($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=x4()[M3($,Z)];return J!=null&&J<Rj?Z:`${Z}[1m]`}function B2($,Z){return x4()[M3($,Z)]}var Rj=1e6,E4=null;var S4=O(()=>{V0();f();x0()});var T3={};N$(T3,{toolsFromProfile:()=>uQ,settingSourcesFromProfile:()=>cQ,resolveClaudeExecutableConfig:()=>N3,resetClaudeContextWindowCache:()=>bj,readProjectMcpServers:()=>lQ,readLastCallUsageFromTranscript:()=>gQ,claudeTranscriptPath:()=>B8,claudeTranscriptDir:()=>K8,claudeManagedSkillOptions:()=>hQ,buildClaudeSpawnPath:()=>IQ,assertClaudeCodeAvailable:()=>R3,ClaudeAgentProcess:()=>_8,CLAUDE_PERMISSION_MODE:()=>pQ});import{existsSync as vQ,readFileSync as wQ}from"node:fs";import{homedir as G8}from"node:os";import{spawn as Tj}from"cross-spawn";import{delimiter as CQ,join as M1}from"node:path";import{EventEmitter as Ej}from"node:events";function hQ($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function xj($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function Sj($){let Z=Tj($.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 R3(){N3(),R7("claude","@anthropic-ai/claude-agent-sdk")}function N3($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?h.claude.bin:$.configuredBin;if(J){if(!($.exists??vQ)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&xj(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:Sj,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function IQ(){if(process.platform==="win32")return process.env.PATH??"";let $=[M1(G8(),".local","npm-global","bin"),M1(G8(),".local","bin"),M1(G8(),".bun","bin"),...(process.env.PATH??"").split(CQ),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(CQ)}function Cj($){let Z=H2($);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 bQ($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function K8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||M1(G8(),".claude");return M1(J,"projects",Z)}function B8($,Z){return M1(K8($),`${Z}.jsonl`)}function gQ($){let Z;try{Z=wQ($,"utf8")}catch{return null}let J=Z.split(`
101
+ `);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 bj(){A3.clear()}function kj($){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)+_2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+_2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+_2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+_2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+_2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let H=_2(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 W8($){return{...$}}function U3($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function yj($,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 _2($){return typeof $==="number"&&Number.isFinite($)?$:0}function mQ($){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(`
102
+ `);return $==null?"":JSON.stringify($,null,2)}function vj($){let Z=mQ($);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(`
103
+ `)}}catch{}return Z}function wj($){return`server_tool:${$}`}function fj($){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 hj($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function Ij($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[d$];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(d$)?d$:Z[0]}}function cQ($){if(!$?.settingSources)return[...yQ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...yQ]}function uQ($){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 lQ($){let Z=M1($,".mcp.json"),J;try{J=wQ(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 gj($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>mj(Y)).filter((Y)=>Y!==null)}function mj($){let Z=$&&typeof $==="object"?$:{question:$},J=O3(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=pj(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 pj($){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=O3(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let V=O3(Y.description,Y.detail,Y.preview);Z.push(V?{label:Q,description:V}:{label:Q})}return Z}function O3(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var fQ,A3,pQ="default",yQ,_8;var j2=O(()=>{J2();k0();f();B0();D3();S4();fQ=class fQ{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($))}};A3=new Map;yQ=["project","local"];_8=class _8 extends Ej{provider="claude";tokenSourceId;opts;input=new fQ;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;queryStart;initializationError=null;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(($)=>{if(this.initializationError=$ instanceof Error?$:Error(String($)),this.emit("error",this.initializationError),!this.query)this.finishExit(1,null)})}async*validatedInput(){if(await this.queryStart,this.initializationError||!this.alive)return;yield*this.input}async initializeQuery(){let $=T4(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??cQ(Z),Y=hQ(J,this.opts.managedSkillPluginPath),Q=uQ(Z),V=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?lQ(this.opts.workDir):void 0;try{let X=N3(),{query:z}=await NY();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:IQ(),...h.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.opts.validateAccount?this.validatedInput():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:pQ,env:G,settingSources:[...J],...this.opts.settings?{settings:this.opts.settings}:{},...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.initializationError=z,this.emit("error",z),this.finishExit(1,null);return}if(this.readLoop(this.query),this.opts.validateAccount)try{this.opts.validateAccount(await this.query.accountInfo())}catch(X){this.initializationError=X instanceof Error?X:Error(String(X)),this.emit("error",this.initializationError),await this.kill()}}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(" ")+`
104
+
105
+ `:"";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.initializationError)throw this.initializationError;if(!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");return(await this.query.supportedModels()).map(Ij)}async readSubscriptionUsage(){if(!this.started)this.sendInitialize();if(await this.queryStart,this.initializationError)throw this.initializationError;if(!this.query||!this.alive)throw Error("Claude 订阅额度查询连接未就绪或已退出");let $=this.query.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET;if(typeof $!=="function")throw Error("当前 Claude SDK 不支持原生订阅额度查询,需更新 Agent 或适配其接口");return $.call(this.query,{skipBehaviors:!0})}async setModelSettings($,Z){let J=T4($);if(!D0(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.initializationError)throw this.initializationError;if(!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 P1)},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=gj(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=fj(Q.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(hj(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,wj(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,vj(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=mQ(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
106
+ `):"",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=Cj($.usage),J=$.modelUsage??$.model_usage,Y=kj(J);if(!Z&&!Y.usage)K(`claude-agent-process: result usage missing rootKeys=${U3($).join(",")||"-"} usageKeys=${U3($.usage).join(",")||"-"} modelUsageKeys=${U3(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=W8(Y.usage),this.lastTotalUsage=W8(Y.usage);else if(Z)this.cumulativeUsageFromResults=yj(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=W8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?W8(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=kQ(this.opts.model,this.tokenSourceId);if(A3.set(X,Y.contextWindow),this.tokenSourceId)for(let[z,W]of Object.entries(J??{})){let G=W?.contextWindow;if(typeof G==="number"&&G>0)SQ(this.tokenSourceId,z,G)}}this.lastContextWindow=A3.get(kQ(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=B8(this.opts.workDir,this.sessionId??""),V=gQ(Q);if(this.lastContextTokens=bQ(V)??(vQ(Q)?bQ(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(`
107
+ `):String($.result??$.error??$.api_error_message??H)}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,checkpoint:!this.lastResult.is_error&&this.lastAssistantUuid&&this.sessionId?{provider:"claude",kind:"assistant-message",id:this.lastAssistantUuid,source:{provider:"claude",sessionId:this.sessionId,cwd:this.opts.workDir}}:null})}failTurnStart($){this.turnActive=!1,this.lastAssistantUuid=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"claude_turn_start_failed",is_error:!0},this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:$.message})}}});var aQ={};N$(aQ,{waitForTokenSourceModelRefresh:()=>M2,tokenSourceRuntimeModels:()=>q2,tokenSourceRuntimeModel:()=>q$,tokenSourceProcessRevision:()=>P2,tokenSourceFactories:()=>D2,setDefaultTokenSource:()=>x3,scrubDshEnv:()=>C4,scrubAnthropicEnv:()=>r0,resetTokenSourceRegistry:()=>S3,registerTokenSourceFactory:()=>M0,registerTokenSource:()=>E3,refreshAllTokenSourceModels:()=>k4,pendingTokenSourceModelRefresh:()=>F2,listTokenSourcesByAgent:()=>nQ,listTokenSources:()=>b$,listEnabledTokenSourcesByAgent:()=>q8,getTokenSourceForAccount:()=>H0,getTokenSource:()=>P$,ANTHROPIC_ENV_KEYS:()=>L8});function r0($){let Z={...$};for(let J of L8)delete Z[J];return Z}function C4($){let Z=r0($);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 q$($,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 M0($){dQ.set($.kind,$)}function D2(){return[...dQ.values()]}function E3($,Z){if(b4.set($.id,$),Z?.default||j8===null)j8=$.id}function P$($){return $?b4.get($):void 0}function H0($,Z="default"){let J=P$($);return J?.forAccount?J.forAccount(Z):J}function b$(){return[...b4.values()]}function nQ($){return b$().filter((Z)=>Z.agent===$)}function q8($){return nQ($).filter((Z)=>Z.enabled)}function x3($){if(b4.has($))j8=$}function S3(){b4.clear(),j8=null,iQ++}function k4(){let $=iQ;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 L8,dQ,b4,j8=null,iQ=0,L2=null;var Y0=O(()=>{f();L8=["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"];dQ=new Map;b4=new Map});import{spawn as cj}from"cross-spawn";import{EventEmitter as uj}from"node:events";import{StringDecoder as lj}from"node:string_decoder";import{createHash as dj}from"node:crypto";function b3($,Z){if(w4.set($,Z),Z.state==="ok")D8.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")D8.delete($)}function rQ($,Z,J=(Y)=>new U1({accountId:Y})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Y=P8.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 M8(()=>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=D$.get($),B;try{B=k3(await M8(()=>V.request("account/rateLimits/read",{})),z.planType)}catch(_){B={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(D$.get($)!==G)B={state:"auth_failed"};else b3($,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(P8.get($)?.promise===Q)P8.delete($)});return P8.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 ij($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function F8($){if(!$)return null;return{percent:ij($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function nj($){let Z=F8($?.primary),J=F8($?.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 aj($){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}=nj(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 oj($){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 tQ($,Z=u){let J=oj($),Y=w4.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],V=Q.filter((H)=>oQ(H.fiveHour,F8($?.primary))&&oQ(H.weekly,F8($?.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 oQ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function rj($){let Z=new U1({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await sQ(Z.request("account/read",{}),C3))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await M8(()=>Z.request("account/rateLimits/read",{}));return k3(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 k3($,Z){let{buckets:J,defaultLimitId:Y}=aj($),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=o7(V,Q.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:dj("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 eQ($=u){return w4.get($)??null}function $V($=u){return D8.get($)??null}function A1($=u){let Z=y4.get($);if(Z)return Z;let J=D$.get($)??0,Y=Promise.resolve().then(()=>rj($)).catch((Q)=>{return K(`usage: ${$} fetch failed: ${Q}`),{state:"network",reason:String(Q)}}).then((Q)=>{if((D$.get($)??0)!==J)return{state:"auth_failed"};return b3($,Q),Q}).finally(()=>{if(y4.get($)===Y)y4.delete($)});return y4.set($,Y),Y}function U8($,Z=u){let J=v4.get(Z);if(J)return J;let Y=D$.get(Z)??0,Q=M8(()=>$("account/rateLimits/read",{})).then((V)=>{if((D$.get(Z)??0)!==Y)return null;let H=k3(V);if((D$.get(Z)??0)===Y)b3(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}`),(D$.get(Z)??0)===Y)w4.delete(Z);return null}).finally(()=>{if(v4.get(Z)===Q)v4.delete(Z)});return v4.set(Z,Q),Q}function U2($){D$.set($,(D$.get($)??0)+1),w4.delete($),D8.delete($),y4.delete($),v4.delete($)}async function M8($,Z="额度查询"){let J=[1000,4000];for(let Y=0;;Y++)try{return await sQ($(),C3)}catch(Q){let V=Q instanceof Error?Q.message:String(Q);if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(V))throw Q;if(Y>=J.length)throw Error(`Codex ${Z}失败(已尝试 ${Y+1} 次):${V}`,{cause:Q});K(`usage: ${Z} retry ${Y+1}/${J.length} in ${J[Y]}ms: ${V}`),await new Promise((X)=>setTimeout(X,J[Y]))}}var C3=1e4,w4,D8,y4,P8,U1,v4,D$;var k$=O(()=>{F1();f();k0();m0();w4=new Map,D8=new Map,y4=new Map;P8=new Map;U1=class U1 extends uj{proc;buf="";decoder=new lj("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??u;this.proc=cj($.bin??A4(),["app-server","--listen","stdio://",...$.args??k.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??k.env(Z,{...process.env,...h.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}`))}),i$(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
107
108
  `))>=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
109
  `);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=x3){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)}}};w4=new Map,P$=new Map});import{existsSync as ij,readFileSync as nj}from"node:fs";class tQ{deps;constructor($){this.deps=$}blocks(){if(!ij(this.deps.stateFile))return[];let $=JSON.parse(nj(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"?A4($.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=n7($.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 U=P?.state==="ok"?P.accountFingerprint??this.deps.identity(q.id):null;if(U)T=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: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,...a7(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 U=a7(P??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(T)U={...U,state:"miss",score:null,reason:T};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"?n7(P,Z.model):null,S=V.find((b)=>(b.identity===D||b.identity===`record:${q.id}`)&&b.meter===M);if(S&&P?.state==="ok"&&U.state==="ready"){let b=A4(P,Z.model);if(!J&&S.windows.some((y)=>{let g=b[y.kind];return g&&g.percent!==null&&(y.percent!==null&&g.percent<y.percent||y.reset!==null&&y.reset<=H&&(g.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 R8;var C3=O(()=>{p0();w$();Y0();V0();S0();f();R8=new tQ({accounts:()=>k.list(),usage:E1,cachedUsage:sQ,identity:($)=>k.fingerprint($),pendingLogin:Z8,now:Date.now,stateFile:nJ,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 aj}from"node:events";function sj($,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 oj="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",rj,k3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),y3;var eQ=O(()=>{p0();C3();w$();f();rj=["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"];y3=class y3 extends aj{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??k3()}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??R8}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){let z=Y.candidates.some((W)=>W.state==="miss"&&!W.duplicateOf)?"Codex 账号检查失败,无法自动选账号(MISS)":Y.candidates.length?"没有符合条件的 Codex 账号":"没有配置 Codex 账号";throw Error(`${z}${Q?`;${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??sj)(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,o$(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 rj)$.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 O8(()=>$.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?oj: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={...k3(),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={...k3(),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 f4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new y3({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(B,_,j,q,P)=>f4({...$,model:q,effort:P,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:B,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??u,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=U2(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 q3({...$,model:X,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(O3(),!U0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new L8({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"]}:{},...J?.claudeSettings?{settings:J.claudeSettings}:{},...J?.validateClaudeAccount?{validateAccount:J.validateClaudeAccount}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!s0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let W=new j2({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 o$(W,Z),{process:W,sourceRevision:V}}var w3=O(()=>{_0();OQ();S4();O1();Y0();p0();eQ()});function N8($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function N2($){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 T2($,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())?`${N2($.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 ZV={};E$(ZV,{codexAccountSummary:()=>h4,codexAccountPanel:()=>I4,codexAccountCard:()=>H$,CODEX_ACCOUNTS_PAGE_SIZE:()=>T8});function $1($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function v3($){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 h4($){let[Z,J]=$V[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function H$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:h4($)}},body:{elements:[I4($)]}}}function I4($){let[,,Z]=$V[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(w0(["连接","授权","就绪"].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(v3([[c0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[w0(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),c0("登录账号,输入左侧验证码")]]))}if($.current)J.push(v3([[c0("当前使用"),w0(`**${$1($.current)}**`)],...$.selected&&$.selected!==$.current?[[c0("下次启动"),w0(`**${$1($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(w0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>$1(Y)).join(" · ")));if($.message)J.push(w0($1($.message)));if($.resetUsage){let Y=$.resetUsage;if(J.push(w0(`**重置卡** ${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(...T2(Q,V))}else J.push(w0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...tj($));if($.phase==="accounts")J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"⌨️ Codex 命令"},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",elements:[w0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
112
- `)),c0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(c0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[w0($1($.details))]});return{tag:"collapsible_panel",element_id:N.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:h4($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function tj($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/T8)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[c0(`${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(c0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let H of Z.entries.slice((Y-1)*T8,Y*T8)){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(c0(`与「${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"?w0(`**#${j+1} · ${G.score.toPrecision(3)} 份/h**`):c0(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(c0(`周余量 ${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:[w0($1(G.reason))]})}if(z.state!=="ok"){if(W.push(w0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[w0($1(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(c0(`${B} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([j,q])=>j?[T2(j,q)]:[]);if(_.length)W.push(v3(_))}if(J>1)Q.push(c0(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}var T8=4,$V,w0=($)=>({tag:"markdown",content:$}),c0=($)=>({tag:"markdown",content:`<font color='grey'>${$1($)}</font>`,text_size:"notation"});var E2=O(()=>{b0();$V={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 JV($){if(!$||typeof $!=="object")return!1;let Z=$.response?.status??$.status,J=$.response?.data?.code??$.code;if(J===99991400||J===230020||J===1061045||ej.has(Z))return!0;if(typeof Z==="number"&&Z>=400)return!1;if($L.has(J)||$.name==="TimeoutError")return!0;return $.cause!==$&&JV($.cause)}function ZL($){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 x1($,Z){for(let J=0;;J++)try{return await Z()}catch(Y){let Q=Math.max(f3[J]??0,ZL(Y)),V=JV(Y)&&J<f3.length&&Q<=60000;if(K(`feishu: ${$} attempt ${J+1}/${f3.length+1} failed: ${Y}; ${V?`retry in ${Q}ms`:"FINAL"}`),!V)throw Y;await new Promise((H)=>setTimeout(H,Q))}}async function x2($,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 D$(`${Z} HTTP ${$.status}: invalid JSON — ${J.slice(0,200)}`,$.status,void 0,Y)}if(!$.ok||Q?.code!==0)throw new D$(`${Z} HTTP ${$.status} code=${Q?.code??"MISS"} msg=${Q?.msg??"MISS"}`,$.status,Q?.code,Y);return Q}var f3,ej,$L,D$;var E8=O(()=>{f();f3=[1000,4000],ej=new Set([408,429,500,502,503,504]),$L=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"]);D$=class D$ extends Error{status;code;retryAfter;constructor($,Z,J,Y){super($);this.status=Z;this.code=J;this.retryAfter=Y;this.name="FeishuRequestError"}}});function YL($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!JL.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 m4{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 YV($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class I3{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 h3($){if(Array.isArray($))return`[${$.map(h3).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)}:${h3(J)}`).join(",")}}`}function QL($){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${h3(V)}`}function VL($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${QL($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function HL(){return new Promise(($)=>setTimeout($,0))}function g4($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function QV($){let Z=$.afterAck??HL,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=YL(Q);if(V)return $.responses.invalid(Q,V);let H=VL(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(_){g4($.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(_){g4($.deduper,H,!1),J(_);return}if(B){let _=B.then((j)=>{g4($.deduper,H,j==="complete")},(j)=>{g4($.deduper,H,!1),J(j)});$.track(_);return}g4($.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 JL;var g3=O(()=>{JL=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 XL}from"node:async_hooks";class VV{actor=new m4;context=new XL;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 F$($,Z){return zL.run($,Z)}var zL;var m3=O(()=>{g3();zL=new VV});async function p3($){let Z=await l3("feishu chat.get",()=>X0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)x8("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 c3($,Z){let J=await l3("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)x8("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 u3($){let Z=await l3("feishu tasklist.delete",()=>X0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)x8("feishu tasklist.delete",Z)}function HV($,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 l3($,Z){try{return await Z()}catch(J){x8($,J)}}function x8($,Z){throw Error(HV($,Z))}var XV=O(()=>{t()});var Q0={};E$(Q0,{writeAliveMarker:()=>W5,urgentApp:()=>C1,uploadImageKey:()=>P5,uploadAndSend:()=>r4,updateCard:()=>A$,unbindSessionChat:()=>C8,tempProjectName:()=>M$,tempChatName:()=>Q5,setPendingConversationLaunchChecked:()=>J1,sendTextRaw:()=>w,sendText:()=>E,sendImage:()=>m8,sendFile:()=>bV,sendCard:()=>c,sanitizeSessionName:()=>F5,resolveProjectDir:()=>w8,replaceTurnAnchors:()=>$$,registerTempSessionLease:()=>s3,refreshChatList:()=>a4,readAliveMarker:()=>G5,provisionProject:()=>D5,projectProfile:()=>C2,preferredChatForSession:()=>q0,loadTempSessionLeases:()=>r3,loadSessionTurnsMap:()=>J5,loadSessionResumeMap:()=>$5,loadSessionModelMap:()=>V5,loadSessionChatMap:()=>e3,listNormalChatIdsByName:()=>f8,isOpenAIChatGPTAuthenticated:()=>s4,hasTempSessionLease:()=>t3,getTurnAnchors:()=>d4,getTenantToken:()=>U$,getSessionResumeRef:()=>Z1,getSessionModelSelection:()=>X5,getSessionBranchBase:()=>i4,getPendingConversationLaunch:()=>n4,getChatTailMessageId:()=>q5,formatFeishuApiError:()=>HV,findNormalChatIdByName:()=>h8,fetchChatOwnerOpenId:()=>p3,fetchChatName:()=>L5,ensureChatForSession:()=>K5,downloadAttachment:()=>o4,disbandChatForSessionExact:()=>j5,disbandChatForSession:()=>_5,deleteTasklistByGuid:()=>u3,deleteReaction:()=>k0,createTempChatForSession:()=>B5,createTasklistWithOwner:()=>c3,client:()=>X0,clearSessionResumeChecked:()=>k2,clearSessionConversationState:()=>z5,chatNameCache:()=>P0,chatIdForSession:()=>v8,bindSessionToChat:()=>b2,bindSessionResumeChecked:()=>l4,bindSessionModelChecked:()=>b1,bindSessionModel:()=>H5,appendTurnAnchorChecked:()=>Y5,addReaction:()=>l0,PROJECTS_ROOT:()=>UV,MAX_UPLOAD_BYTES:()=>g8});import*as jV from"@larksuiteoapi/node-sdk";import{execSync as WL}from"node:child_process";import{randomUUID as o3}from"node:crypto";import{mkdirSync as i3,readFileSync as S1,statSync as LV,writeFileSync as qV}from"node:fs";import{readFile as GL}from"node:fs/promises";import{homedir as zV}from"node:os";import{basename as S2,extname as KL,isAbsolute as PV,join as b8}from"node:path";import{sync as BL}from"cross-spawn";function n3(){let $={};for(let[Z,J]of u0)$[Z]=J;s(G7,$)}function r3(){u0.clear();try{let $=JSON.parse(S1(G7,"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"||!M$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){K(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}u0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}K(`feishu: loaded ${u0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")K(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function s3($,Z){if(!M$($))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 u0.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=u0.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};u0.set(Z,Y);try{n3()}catch(Q){if(J)u0.set(Z,J);else u0.delete(Z);throw Q}}function t3($,Z){let J=u0.get(Z);return J?.sessionName===$&&J.chatId===Z}function C2($){return h.projects[$]}function w8($){return C2($)?.cwd?.trim()||b8(UV,$)}function u4($,Z={}){return $0($,{...Z,signal:Z.signal??AbortSignal.timeout(MV)})}async function AV($,Z,J){let Y=Z.signal??AbortSignal.timeout(MV);try{return await x2(await u4($,{...Z,signal:Y}),J)}catch(Q){if(Y.aborted&&Y.reason?.name==="TimeoutError")throw Y.reason;throw Q}}async function U$(){if(S8&&Date.now()<WV)return S8;return d3??=(async()=>{let $=await AV("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:DV,app_secret:FV})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return S8=$.tenant_access_token,WV=Date.now()+Math.max(0,($.expire??7200)-60)*1000,S8})().finally(()=>{d3=null}),d3}function e3(){try{let $=JSON.parse(S1(H7,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")q0.set(Z,J);K(`feishu: loaded ${q0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function OV(){try{a3()}catch($){K(`feishu: save session-chat-map failed: ${$}`)}}function a3(){let $={};for(let[Z,J]of q0)$[Z]=J;s(H7,$)}function b2($,Z){if(q0.get($)===Z)return;let J=q0.get($);q0.set($,Z),OV(),K(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function C8($){let Z=q0.get($);if(!Z)return;q0.delete($),OV(),K(`feishu: unbound session "${$}" from ${Z}`)}function p4($,Z){let J=L0.get($)??{};J[Z.provider]=Z,L0.set($,J)}function GV($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=_$(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"||!PV(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function KV($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!_$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!PV($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function _L($,Z,J){if(typeof $!=="string")return KV($);if(!Z)throw Error("cannot bind a conversation without a provider");return KV({provider:Z,sessionId:$,cwd:J??null})}function $5(){try{let $=JSON.parse(S1(X7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");L0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){p4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=GV(Y);if(Q){p4(Z,Q);continue}for(let V of C7){let H=Y[V];if(typeof H==="string"&&H.trim()){p4(Z,{provider:V,sessionId:H.trim(),cwd:null});continue}let X=GV(H,V);if(X)p4(Z,X)}}K(`feishu: loaded ${L0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function k8(){let $={};for(let[Z,J]of L0){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(X7,$)}function l4($,Z,J,Y){let Q=_L(Z,J,Y),V=L0.get($),H=V?{...V}:void 0,X=V?.[Q.provider];if(X?.sessionId===Q.sessionId&&X.cwd===Q.cwd)return;p4($,Q);try{k8()}catch(z){if(H)L0.set($,H);else L0.delete($);throw z}}function Z1($,Z="codex"){let J=L0.get($)?.[Z];return J?{...J}:null}function k2($,Z){let J=L0.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)L0.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)L0.delete($);else L0.set($,Q)}try{k8()}catch(Q){throw L0.set($,Y),Q}}function RV($){if(!$||typeof $!=="object")return null;let Z=$;if(!_$(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 NV($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=RV(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 TV($){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=RV(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=NV(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{j0(Y,J.provider)}catch{return null}return Y}function jL($){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 LL($,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=NV(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:jL(J.writes)}}function qL($){if(!$||typeof $!=="object")return null;let Z=$,J=TV(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 Z5($){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 J5(){try{let $=JSON.parse(S1(z7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");e.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 _=TV(B.base);if(!_){J++;continue}H=_}if(Object.prototype.hasOwnProperty.call(B,"pendingLaunch")){let _=qL(B.pendingLaunch);if(!_){J++;continue}X=_}}else{J++;continue}let z=L0.get(Y),W=z?.claude!==void 0&&z.codex===void 0?"claude":null,G=[];for(let B of V){let _=LL(B,W);if(_)G.push(_);else J++}if(G.length||H!==null||X)e.set(Y,{base:H,anchors:G,...X?{pendingLaunch:X}:{}}),Z+=G.length}if(K(`feishu: loaded ${Z} turn anchors across ${e.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 c4(){let $={};for(let[Z,J]of e)$[Z]=J;s(z7,$)}function Y5($,Z){let J=e.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>BV){let V=Y.splice(0,Y.length-BV),H=V[V.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}e.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{c4()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function d4($){return e.get($)?.anchors??[]}function i4($){return e.get($)?.base??null}function n4($){let Z=e.get($)?.pendingLaunch;return Z?Z5(Z):null}function J1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");j0(Z.launch,"claude",Z.launch.source.cwd)}let J=e.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)e.delete($);else e.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:Z5(Z)}:{}});try{c4()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function $$($,Z,J,Y){let Q=e.get($),V=Y===void 0?Q?.pendingLaunch:Y??void 0,H=V?Z5(V):void 0;if(Z.length===0&&J===null&&!H)e.delete($);else e.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{c4()}catch(X){if(Q)e.set($,Q);else e.delete($);throw X}}function M$($){return _V.test($)?$.replace(_V,""):null}function Q5($,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([...P0.values(),...e.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;V.has(H);X++)H=`${$}*${Q}-${X}`;return H}function V5(){try{let $=JSON.parse(S1(W7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){C0.set(Z,{provider:W2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,V=_$(Q)?Q:typeof Y==="string"&&Y.trim()?W2(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"?U0(X)?X:null:s0(X)?X:null;C0.set(Z,{provider:V,model:H,effort:G,...W?{tokenSourceId:W}:{}})}K(`feishu: loaded ${C0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-model-map failed: ${$?.message??$}`)}}function PL(){try{y8()}catch($){K(`feishu: save session-model-map failed: ${$}`)}}function y8(){let $={};for(let[Z,J]of C0)$[Z]=J;s(W7,$)}function H5($,Z,J,Y,Q){let V=C0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;C0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),PL()}function b1($,Z,J,Y,Q){let V=C0.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;C0.set($,H);try{y8()}catch(X){if(V)C0.set($,V);else C0.delete($);throw X}}function X5($){let Z=C0.get($);if(Z)return Z;let J=M$($);return J?C0.get(J)??null:null}function z5($){let Z=q0.get($),J=L0.get($),Y=C0.get($),Q=e.get($),V=[...u0.entries()].filter(([,H])=>H.sessionName===$);q0.delete($),L0.delete($),C0.delete($),e.delete($);for(let[H]of V)u0.delete(H);try{a3(),k8(),y8(),c4(),n3()}catch(H){if(Z)q0.set($,Z);if(J)L0.set($,J);if(Y)C0.set($,Y);if(Q)e.set($,Q);for(let[z,W]of V)u0.set(z,W);let X=[H];for(let z of[a3,k8,y8,c4,n3])try{z()}catch(W){X.push(W)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function W5($){s(B7,$)}function G5(){let $;try{$=S1(B7,"utf8")}catch(J){if(J.code==="ENOENT")return[];throw J}let Z=JSON.parse($);if(!Array.isArray(Z)||Z.some((J)=>typeof J!=="string"||!J.trim()))throw Error("invalid alive session marker: expected non-empty session names");return Z}function v8($){let Z=q0.get($);if(Z){let Y=P0.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 P0)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 a4(){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)P0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);K(`feishu: refreshed chat list — ${P0.size} groups`)}catch($){K(`feishu: refresh chat list failed: ${$}`)}}async function f8(){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;P0.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 h8($){let Z=q0.get($);if(Z&&P0.get(Z)===$){let V=await EV(Z);if(V.name===$&&xV(V.status))return Z;P0.delete(Z),C8($)}let Y=(await f8()).get($)??[];if(Y.length===0)return null;let Q=q0.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 K5($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await h8($);if(J){let V=await DL(J,Z);return b2($,J),{chatId:J,created:!1,joined:V}}let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:o3()},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 P0.set(Q,$),b2($,Q),{chatId:Q,created:!0,joined:!0}}async function B5($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await h8($))throw Error(`temporary group name already exists: ${$}`);let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:o3()},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 P0.set(Q,$),b2($,Q),{chatId:Q,created:!0,joined:!0}}async function _5($){let Z=await h8($);if(!Z)return C8($),{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(P0.delete(Z),q0.get($)===Z)C8($);return{chatId:Z,disbanded:!0}}async function j5($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await EV(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!xV(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 P0.delete(Z),{chatId:Z,disbanded:!0}}async function DL($,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 L5($){try{let Z=await U$(),Y=await(await u4(`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 P0.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 I8($,Z,J,Y){let Q=o3();try{return await x1(`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 D$(`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 EV($){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 xV($){return $===null||$==="normal"}async function E($,Z){return F$($,()=>I8("Text",$,"text",JSON.stringify({text:Z})))}async function c($,Z){return F$($,()=>I8("Card",$,"interactive",JSON.stringify(s$(Z))))}async function q5($){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 A$($,Z){let J=await X0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(s$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){return F$($,()=>FL($,Z))}async function FL($,Z){try{let J=await U$(),Q=await(await u4("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 l0($,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 k0($,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 C1($,Z){if(!$){K("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){K(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await U$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await u4(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 o4($,Z,J,Y){try{let Q=await U$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await u4(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());i3(_7,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,W=b8(_7,`${Date.now()}-${z}`);return qV(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 ML($){return UL.has(KL($).toLowerCase())}async function SV($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Y;return x1(`${J} ${$}`,async()=>{if(Y??=new Blob([Uint8Array.from(await GL($))]),Y.size>g8)throw Error(`${S2($)} 超过 30 MB`);let Q=await U$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",S2($));V.append(Z,Y,S2($));let X=(await AV(`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 P5($){try{let Z=LV($);if(!Z.isFile())return K(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>g8)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 SV($,"image")}catch{return null}}async function m8($,Z){return F$($,()=>I8("Image",$,"image",JSON.stringify({image_key:Z})))}async function bV($,Z){return F$($,()=>I8("File",$,"file",JSON.stringify({file_key:Z})))}async function r4($,Z){try{let Q=LV(Z);if(!Q.isFile())return K(`feishu: uploadAndSend not a file — ${Z}`),await E($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>g8)return K(`feishu: uploadAndSend oversize — ${Z} (${Q.size}B)`),await E($,`❌ 出站文件: ${S2(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return K(`feishu: uploadAndSend stat failed — ${Z}: ${Q}`),await E($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=ML(Z)?"image":"file",Y=J==="image"?"出站图片":"出站文件";try{let Q=await SV(Z,J),V=await(J==="image"?m8($,Q):bV($,Q));if(!V)return K(`feishu: uploadAndSend ${Z} send failed after upload`),await E($,`❌ ${Y}发送失败: ${S2(Z)}(上传已完成)`),!1;return K(`feishu: uploadAndSend ${Z} delivered msg=${V}`),!0}catch(Q){return K(`feishu: uploadAndSend ${Z} failed: ${Q}`),await E($,`❌ ${Y}上传失败: ${S2(Z)} — ${Q}`),!1}}function D5($){i3($,{recursive:!0}),K(`feishu: provisioned ${$}`);let Z=b8(zV(),".codex","config.toml");try{i3(b8(zV(),".codex"),{recursive:!0});let J="";try{J=S1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
113
-
114
- `:""}${Y}
115
- trust_level = "trusted"
116
- `,qV(Z,J)}}catch(J){K(`feishu: codex trust write failed for ${$}: ${J}`)}try{WL("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function s4($=u){let Z=BL(O4(),["login","status",...k.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:k.env($,{...process.env,...h.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 F5($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var DV,FV,UV,u0,X0,MV=15000,S8="",WV=0,d3=null,P0,q0,L0,e,BV=200,_V,C0,g8=31457280,UL;var t=O(()=>{h0();E8();m3();_0();y0();O1();_0();V0();f();p0();S0();b0();A1();XV();DV=h.feishu.app_id,FV=h.feishu.app_secret,UV=h.runtime.projects_root,u0=new Map;X0=new jV.Client({appId:DV,appSecret:FV,disableTokenCache:!1});P0=new Map,q0=new Map;L0=new Map;e=new Map;_V=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;C0=new Map;UL=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as CV,randomUUID as AL}from"node:crypto";function t4($,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 kV($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function z$($){let Z=X$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function Z$($){return!X$.has($)}function d0($,Z,J){X$.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 e4($){return X$.get($)?.elementCount??0}function yV($){let Z=X$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function y2($,Z){return X$.get($)?.deadElements.has(Z)??!1}function wV($,Z){let J=X$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function $9($){let Z=z$($);return Z.sequence+=1,Z.sequence}function U5($,Z){$.deadElements.add(Z)}function vV($){return CV("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function EL($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==N.footer)Y.push(J);return CV("sha256").update(Y.sort().join(`
118
- `)).digest("hex")}async function y1($,Z,J){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:AL()}:{}}):void 0,Q=`cardkit ${$} ${Z}`;return x1(Q,async()=>{let V=await U$(),H=AbortSignal.timeout(RL),X;try{return X=await $0(`${OL}${Z}`,{method:$,headers:{Authorization:`Bearer ${V}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:H}),(await x2(X,Q))?.data}catch(z){if(H.aborted&&H.reason?.name==="TimeoutError")throw H.reason;if(X&&z instanceof D$){let W=X.headers.get("x-tt-logid")??X.headers.get("x-request-id")??X.headers.get("request-id")??void 0;if(Object.assign(z,{httpStatus:X.status,logId:W}),W)z.message+=` log_id=${W}`}throw z}})}function xL($){return new Promise((Z)=>setTimeout(Z,$))}function SL($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function bL($){let Z=$9($);await y1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function p8($,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(t4(W.code,W))W.capacityFingerprint=EL(z$($),V.elementId,V.contentFingerprint);try{if(!Q)z$($).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(!SL(X)){K(`cardkit ${Z} ${$}: ${X}`),H(X);return}K(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await bL($)}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 CL($){return typeof $==="object"&&$!==null&&$.code===200740}async function J$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:NL,Y=null;for(let Q=0;Q<J.length;Q++){let V=J[Q]??0;if(V>0)await xL(V);try{let H=await y1("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,!CL(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 O$($){let Z=X$.get($);if(!Z)return;await Z.queue}function A0($,Z,J={},Y){if(Z$($))return Promise.resolve();let Q=z$($);if(Q.closing)return Promise.resolve();let V=s$(Z),H=V.element_id,X=vV(V),z=()=>{if(!H)return;U5(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>p8($,"addElement",async()=>{let W=$9($);if(await y1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([V]),sequence:W}),Q.elementCount+=1,H!==N.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 J0($,Z,J,Y,Q=!0){if(Z$($))return Promise.resolve();let V=z$($);if(V.closing)return Promise.resolve();let H=s$(J),X=vV(H),z=()=>{U5(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>p8($,`replaceElement ${Z}`,async()=>{let W=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!W&&!V.failedReplacements.has(Z))return;let G=$9($);if(W)await y1("POST",`/cards/${$}/elements`,{type:W.type??"append",...W.targetElementId?{target_element_id:W.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),V.elementCount++;else await y1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.failedReplacements.delete(Z),Z!==N.footer)V.contentFingerprints.set(Z,X)},(W)=>{if(Q)z();Y?.(W.code,W)},!Q,{elementId:Z,contentFingerprint:X})),V.queue}async function O0($,Z,J,Y={}){if(Z$($))return!1;let Q=z$($);if(Q.closing)return!1;let V=!1;return await J0($,Z,J,()=>{V=!0},Y.notifyCardFailure!==!1),!V&&!Q.deadElements.has(Z)}async function fV($,Z,J){if(Z$($))return{landed:!1};let Y=z$($);if(Y.closing)return{landed:!1};let Q;return await J0($,Z,J,(V,H)=>{Q=H}),{landed:!Q&&!Y.deadElements.has(Z),...Q?{failure:Q}:{}}}async function Y1($,Z,J={}){return(await w2($,Z,J)).landed}async function w2($,Z,J={}){if(Z$($))return{landed:!1};let Y=z$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,V;return await A0($,Z,J,(H,X)=>{V=X}),{landed:!V&&!(Q&&Y.deadElements.has(Q)),...V?{failure:V}:{}}}function kL($,Z,J){if(Z$($))return Promise.resolve();let Y=z$($);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(()=>p8($,`deleteElement ${Z}`,async()=>{if(Q())return;let V=$9($);await y1("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),U5(Y,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Y.queue}async function hV($,Z){if(Z$($))return!1;let J=z$($);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 kL($,Z,()=>{Y=!0}),!Y&&J.deadElements.has(Z)}function w1($,Z){if(Z$($)||X$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=k1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},k1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=k1.get($);if(!Q)return;if(Z$($)){k1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let V=Q.latest;D0($,{config:{summary:{content:V}}}).then((H)=>{let X=k1.get($);if(H&&X===Q)X.lastSent=V})},TL)}function N0($){let Z=k1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;k1.delete($)}function c8($,Z){return D0($,Z).then(()=>{})}async function D0($,Z){if(Z$($))return!1;let J=z$($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>p8($,"patchSettings",async()=>{if(Z$($))return;let V=$9($);await y1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:V}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!Z$($)}async function v0($){let Z=X$.get($);if(!Z){N0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,N0($),await Z.queue,X$.delete($)}var OL="https://open.feishu.cn/open-apis/cardkit/v1",RL=15000,NL,X$,k1,TL=1500;var v$=O(()=>{h0();t();E8();f();b0();NL=[0,250,750,1500];X$=new Map,k1=new Map});function IV($){if($===void 0)return"—";if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(2)} GB`}function v2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function M5($){let Z=new URL($);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("文件链接无效");return Z.href.replace(/[()]/g,(J)=>`%${J.charCodeAt(0).toString(16).toUpperCase()}`)}function wL($){let Z=$.split(".").at(-1)?.toLowerCase();if(["mp4","mov","mkv","webm"].includes(Z??""))return"\uD83C\uDFAC";if(["png","jpg","jpeg","webp","gif"].includes(Z??""))return"\uD83D\uDDBC️";if(["zip","7z","tar","gz"].includes(Z??""))return"\uD83D\uDCE6";if(["xlsx","xls","csv"].includes(Z??""))return"\uD83D\uDCCA";return"\uD83D\uDCC4"}function vL($){let Z=v2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${M5($.file.url)})`:Z,Y=$.status==="failed"?`<font color='red'>${v2($.error??"交付失败")}</font>`:`<font color='grey'>${IV($.bytes)}${$.status==="pending"?" · 上传中":""}</font>`;return{tag:"column_set",flex_mode:"none",horizontal_spacing:"12px",columns:[{tag:"column",width:"32px",vertical_align:"center",elements:[{tag:"markdown",content:wL($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
119
- ${Y}`}]}]}}function A5($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Y=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Q=$.folderAccessReady&&$.folder?M5($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],H=V.slice(0,yL),X=V.slice(H.length).filter((z)=>z.status==="failed").length;return{schema:"2.0",config:{update_multi:!0,width_mode:"default",summary:{content:`交付文件 · ${Y}`}},header:{title:{tag:"plain_text",content:"\uD83D\uDCC1 交付文件"},subtitle:{tag:"plain_text",content:`${$.projectName} · ${new Date($.createdAt).toLocaleString("zh-CN",{hour12:!1})}`},template:Z||!J?"blue":"red"},body:{padding:"16px",vertical_spacing:"16px",elements:[{tag:"markdown",content:`**本次交付 · ${Y}**`},{tag:"column_set",element_id:N.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...H.map(vL),...$.files.length>H.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-H.length} 个文件${X?`中有 ${X} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${v2($.error)}</font>`}]:[],...Q?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:Q}]},{tag:"markdown",content:"<font color='grey'>卡片仅列本轮文件;管理入口查看本群全部云空间交付文件,可重命名、移动或删除。</font>",text_size:"notation"}]:[]]}}}function O5($){let Z=!$.settings?"MISS":$.settings.enabled?"云空间交付":"聊天附件(默认)";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"files · 群文件交付"},template:$.error?"red":"blue"},body:{elements:[{tag:"markdown",content:`**当前模式:${Z}**
120
- 群:${v2($.settings?.folder?.name??$.groupName)}`},...$.notice?[{tag:"markdown",content:v2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${v2($.error)}</font>`}]:[],{tag:"column_set",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",elements:[{tag:"markdown",content:"`files on` 开启本群云空间交付\n`files off` 恢复直接发送聊天附件\n`files` 查看本群设置"}]}]},...$.settings?.folder?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:M5($.settings.folder.url)}]}]:[]]}}}var yL=12;var u8=O(()=>{b0()});function l8($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function d8($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function fL($,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 mV($,Z,J){let Y=fL($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function gV($){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 i8($,Z){let J=gV($);return Z!=null&&Z>0?`${J}/${gV(Z)}`:`${J}/--`}function pV($,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 N5($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function a8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function hL($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function IL($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function n8($){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 cV($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function lV($){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 gL($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${lV($)}`}function R5($){return typeof $==="number"&&Number.isFinite($)?$:null}function mL($){let Z=R5($.startedAtMs),J=R5($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${G0((J-Z)/1000)}`}function pL($){let Z=R5($);return Z==null?null:n8(Z)}function cL($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=pL($.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 T5($,Z,J){if($==null||!Number.isFinite($))return null;let Y=mV($,Z,J);return Y?`${Y.used}% · ${i8($,Z)}`:"--"}function E5($){let Z=n8($?.input_tokens??Number.NaN),J=n8($?.cache_read_input_tokens??Number.NaN),Y=n8($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function Z9($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",V=Q?"✅":"⏳",H=Q?mL(Y):"",X=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,z=cL(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
121
- `)}]}}function dV($,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(`- ${hL(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(`
122
- `)}function x5($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:gL($,J)}},expanded:!1,elements:[{tag:"markdown",content:dV($,Z,J)}]}}function J9($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${lV($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:dV($,Z)}]}}function S5($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${cV($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${G0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${cV($.status)}: ${IL($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
123
- `)}]}}function o8($){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:N.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((H)=>({tag:"markdown",content:Z0(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:N.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function iV($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function uL($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function lL($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let V=$.options[Q],H=V.description?` · ${Z0(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:`**${Z0(V.label)}**${H}`}]})}return Y}function uV($,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=iV(X,H,Q),W=Y.get(H);if(W){let G=uL(X,W),B=[`**✅ ${z}**`,`**回答**:${G}`];V.push({tag:"markdown",content:B.join(`
124
- `)});continue}if(H===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),X.options.length>0)V.push(...lL(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 f2($,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(...uV(J,Z,X,H)??[]);let B=[...H.values()].reverse().find((_)=>_.user)?.user;if(B)W.push({tag:"markdown",content:`
125
- *— 由 ${B} 回答*`})}else if(X!==void 0&&J[X])G=`${Y} 等你确认 · ${X+1}/${V}`,W.push(...uV(J,Z,X,H)??[]);else if(G=`${Y} 等你确认`,J[0])W.push({tag:"markdown",content:`**${iV(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:N.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!z&&!Q?.waitingFor,elements:W}}var nV=O(()=>{b0()});import{isAbsolute as b5,relative as dL}from"node:path";function s8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function t8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function nL($){return s8($)||t8($)}function e8($){return $==="FileChange"||$==="fileChange"}function Q9($){return $==="WebSearch"||$==="webSearch"}function $6($){return $==="WebFetch"||$==="webFetch"}function f5($){return $==="MCP"}function V9($){return $==="ImageGeneration"||$==="imageGeneration"}function h5($){return $==="Agent"||$==="Task"}function Z6($){return $==="Read"}function J6($){return $==="Write"}function Y6($){return $==="Edit"||$==="NotebookEdit"}function Q6($){return $==="MultiEdit"}function I5($){return $==="Glob"||$==="Grep"||$==="LS"}function V6($){return $==="TodoWrite"}function H6($){return $==="ExitPlanMode"}function X6($){return $.startsWith(oV)}function rV($){return X6($)?$.slice(oV.length):$}function f1($){if(X6($))return"服务端工具";if(e8($))return"文件变更";if(Q9($))return"网页搜索";if($6($))return"网页读取";if(V9($))return"图片生成";if(Z6($))return"读取文件";if(J6($))return"写入文件";if(Y6($)||Q6($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(V6($))return"更新待办";if(H6($))return"确认计划";if($==="Task")return"子任务";return nL($)?"Bash":$}function Q1($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(X6($))return J(aL($,Z),80);if(!Z||typeof Z!=="object")return"";if(s8($))return oL(Z);if(t8($))return rL(Z);if(e8($))return J(eL(Z),80);if(Q9($))return J(_H(Z),80);if($6($))return J(Hq(Z),80);if(f5($))return J(zq(Z),80);if(V9($))return J(Gq(Z),80);if(h5($))return J(Kq(Z),80);if(Z6($))return J($q(Z),80);if(J6($))return J(Zq(Z),80);if(Y6($))return J(Jq(Z),80);if(Q6($))return J(Yq(Z),80);if(I5($))return J(Qq($,Z),80);if(V6($))return J(Vq(Z),80);if(H6($))return J(H9(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 aL($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:rV($),Y=H9(Z?.input);return Y?`${J}: ${Y}`:J}function oL($){let Z=(V,H)=>V.length>H?V.slice(0,H)+"…":V,J=tV($);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(K2(Y),46)}`}function sV($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function rL($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${sV($)}${J}`}function tV($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=l7(Z);return{description:Y.description||J,command:Y.command}}function i0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
110
+ `,(Y)=>Y?J(Y):Z())})}isAlive(){return this.alive}request($,Z,J=C3){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})+`
111
+ `,(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)}}};v4=new Map,D$=new Map});import{existsSync as sj,readFileSync as tj}from"node:fs";class ZV{deps;constructor($){this.deps=$}blocks(){if(!sj(this.deps.stateFile))return[];let $=JSON.parse(tj(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"?U4($.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=r7($.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,...s7(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=s7(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"?r7(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=U4(P,Z.model);if(!J&&S.windows.some((y)=>{let g=C[y.kind];return g&&g.percent!==null&&(y.percent!==null&&g.percent<y.percent||y.reset!==null&&y.reset<=H&&(g.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 A8;var y3=O(()=>{m0();k$();Y0();V0();x0();f();A8=new ZV({accounts:()=>k.list(),usage:A1,cachedUsage:$V,identity:($)=>k.fingerprint($),pendingLogin:e9,now:Date.now,stateFile:sJ,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=q$(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as ej}from"node:events";function JL($,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 $L="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",ZL,v3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),w3;var JV=O(()=>{m0();y3();k$();f();ZL=["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"];w3=class w3 extends ej{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??v3()}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??A8}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){let z=Y.candidates.some((W)=>W.state==="miss"&&!W.duplicateOf)?"Codex 账号检查失败,无法自动选账号(MISS)":Y.candidates.length?"没有符合条件的 Codex 账号":"没有配置 Codex 账号";throw Error(`${z}${Q?`;${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??JL)(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,i$(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 ZL)$.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 U8(()=>$.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?$L: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={...v3(),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={...v3(),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 f4($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new w3({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(B,_,j,q,P)=>f4({...$,model:q,effort:P,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:B,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??u,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=P2(J,Q),H=!Y&&J&&q$(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||!K0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new P3({...$,model:X,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(R3(),!D0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new _8({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"]}:{},...J?.claudeSettings?{settings:J.claudeSettings}:{},...J?.validateClaudeAccount?{validateAccount:J.validateClaudeAccount}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!o0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let W=new G2({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 i$(W,Z),{process:W,sourceRevision:V}}var f3=O(()=>{B0();xQ();j2();F1();Y0();m0();JV()});function O8($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function YV($){if($===void 0)return"—";if($<1024)return`${$} B`;if($<1048576)return`${($/1024).toFixed(1)} KB`;if($<1073741824)return`${($/1048576).toFixed(1)} MB`;return`${($/1073741824).toFixed(2)} GB`}function A2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function h3($){let Z=new URL($);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("文件链接无效");return Z.href.replace(/[()]/g,(J)=>`%${J.charCodeAt(0).toString(16).toUpperCase()}`)}function QL($){let Z=$.split(".").at(-1)?.toLowerCase();if(["mp4","mov","mkv","webm"].includes(Z??""))return"\uD83C\uDFAC";if(["png","jpg","jpeg","webp","gif"].includes(Z??""))return"\uD83D\uDDBC️";if(["zip","7z","tar","gz"].includes(Z??""))return"\uD83D\uDCE6";if(["xlsx","xls","csv"].includes(Z??""))return"\uD83D\uDCCA";return"\uD83D\uDCC4"}function VL($){let Z=A2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${h3($.file.url)})`:Z,Y=$.status==="failed"?`<font color='red'>${A2($.error??"交付失败")}</font>`:`<font color='grey'>${YV($.bytes)}${$.status==="pending"?" · 上传中":""}</font>`;return{tag:"column_set",flex_mode:"none",horizontal_spacing:"12px",columns:[{tag:"column",width:"32px",vertical_align:"center",elements:[{tag:"markdown",content:QL($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
112
+ ${Y}`}]}]}}function I3($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Y=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Q=$.folderAccessReady&&$.folder?h3($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],H=V.slice(0,YL),X=V.slice(H.length).filter((z)=>z.status==="failed").length;return{schema:"2.0",config:{update_multi:!0,width_mode:"default",summary:{content:`交付文件 · ${Y}`}},header:{title:{tag:"plain_text",content:"\uD83D\uDCC1 交付文件"},subtitle:{tag:"plain_text",content:`${$.projectName} · ${new Date($.createdAt).toLocaleString("zh-CN",{hour12:!1})}`},template:Z||!J?"blue":"red"},body:{padding:"16px",vertical_spacing:"16px",elements:[{tag:"markdown",content:`**本次交付 · ${Y}**`},{tag:"column_set",element_id:R.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...H.map(VL),...$.files.length>H.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-H.length} 个文件${X?`中有 ${X} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${A2($.error)}</font>`}]:[],...Q?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:Q}]},{tag:"markdown",content:"<font color='grey'>卡片仅列本轮文件;管理入口查看本群全部云空间交付文件,可重命名、移动或删除。</font>",text_size:"notation"}]:[]]}}}function g3($){let Z=!$.settings?"MISS":$.settings.enabled?"云空间交付":"聊天附件(默认)";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"files · 群文件交付"},template:$.error?"red":"blue"},body:{elements:[{tag:"markdown",content:`**当前模式:${Z}**
113
+ 群:${A2($.settings?.folder?.name??$.groupName)}`},...$.notice?[{tag:"markdown",content:A2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${A2($.error)}</font>`}]:[],{tag:"column_set",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",elements:[{tag:"markdown",content:"`files on` 开启本群云空间交付\n`files off` 恢复直接发送聊天附件\n`files` 查看本群设置"}]}]},...$.settings?.folder?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:h3($.settings.folder.url)}]}]:[]]}}}var YL=12;var R8=O(()=>{S0()});function N8($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function T8($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function HL($,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 VV($,Z,J){let Y=HL($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function QV($){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 E8($,Z){let J=QV($);return Z!=null&&Z>0?`${J}/${QV(Z)}`:`${J}/--`}function HV($,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 p3($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function S8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function XL($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function zL($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function x8($){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 XV($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function WV($){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 WL($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${WV($)}`}function m3($){return typeof $==="number"&&Number.isFinite($)?$:null}function GL($){let Z=m3($.startedAtMs),J=m3($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${F0((J-Z)/1000)}`}function KL($){let Z=m3($);return Z==null?null:x8(Z)}function BL($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=KL($.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 c3($,Z,J){if($==null||!Number.isFinite($))return null;let Y=VV($,Z,J);return Y?`${Y.used}% · ${E8($,Z)}`:"--"}function u3($){let Z=x8($?.input_tokens??Number.NaN),J=x8($?.cache_read_input_tokens??Number.NaN),Y=x8($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function h4($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",V=Q?"✅":"⏳",H=Q?GL(Y):"",X=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,z=BL(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
114
+ `)}]}}function GV($,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(`- ${XL(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(`
115
+ `)}function l3($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:WL($,J)}},expanded:!1,elements:[{tag:"markdown",content:GV($,Z,J)}]}}function I4($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${WV($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:GV($,Z)}]}}function d3($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${XV($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${F0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${XV($.status)}: ${zL($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
116
+ `)}]}}function C8($){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:Z0(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 KV($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function _L($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function jL($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let V=$.options[Q],H=V.description?` · ${Z0(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:`**${Z0(V.label)}**${H}`}]})}return Y}function zV($,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=KV(X,H,Q),W=Y.get(H);if(W){let G=_L(X,W),B=[`**✅ ${z}**`,`**回答**:${G}`];V.push({tag:"markdown",content:B.join(`
117
+ `)});continue}if(H===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),X.options.length>0)V.push(...jL(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 O2($,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(...zV(J,Z,X,H)??[]);let B=[...H.values()].reverse().find((_)=>_.user)?.user;if(B)W.push({tag:"markdown",content:`
118
+ *— 由 ${B} 回答*`})}else if(X!==void 0&&J[X])G=`${Y} 等你确认 · ${X+1}/${V}`,W.push(...zV(J,Z,X,H)??[]);else if(G=`${Y} 等你确认`,J[0])W.push({tag:"markdown",content:`**${KV(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 BV=O(()=>{S0()});import{isAbsolute as i3,relative as LL}from"node:path";function k8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function y8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function PL($){return k8($)||y8($)}function v8($){return $==="FileChange"||$==="fileChange"}function m4($){return $==="WebSearch"||$==="webSearch"}function w8($){return $==="WebFetch"||$==="webFetch"}function t3($){return $==="MCP"}function p4($){return $==="ImageGeneration"||$==="imageGeneration"}function e3($){return $==="Agent"||$==="Task"}function f8($){return $==="Read"}function h8($){return $==="Write"}function I8($){return $==="Edit"||$==="NotebookEdit"}function g8($){return $==="MultiEdit"}function $5($){return $==="Glob"||$==="Grep"||$==="LS"}function m8($){return $==="TodoWrite"}function p8($){return $==="ExitPlanMode"}function c8($){return $.startsWith(jV)}function LV($){return c8($)?$.slice(jV.length):$}function O1($){if(c8($))return"服务端工具";if(v8($))return"文件变更";if(m4($))return"网页搜索";if(w8($))return"网页读取";if(p4($))return"图片生成";if(f8($))return"读取文件";if(h8($))return"写入文件";if(I8($)||g8($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(m8($))return"更新待办";if(p8($))return"确认计划";if($==="Task")return"子任务";return PL($)?"Bash":$}function r$($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(c8($))return J(DL($,Z),80);if(!Z||typeof Z!=="object")return"";if(k8($))return FL(Z);if(y8($))return ML(Z);if(v8($))return J(OL(Z),80);if(m4($))return J(kV(Z),80);if(w8($))return J(CL(Z),80);if(t3($))return J(kL(Z),80);if(p4($))return J(vL(Z),80);if(e3($))return J(wL(Z),80);if(f8($))return J(RL(Z),80);if(h8($))return J(NL(Z),80);if(I8($))return J(TL(Z),80);if(g8($))return J(EL(Z),80);if($5($))return J(xL($,Z),80);if(m8($))return J(SL(Z),80);if(p8($))return J(c4(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Y of Object.values(Z))if(typeof Y==="string"&&Y)return J(Y,80);return""}function DL($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:LV($),Y=c4(Z?.input);return Y?`${J}: ${Y}`:J}function FL($){let Z=(V,H)=>V.length>H?V.slice(0,H)+"…":V,J=PV($);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(X2(Y),46)}`}function qV($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function ML($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${qV($)}${J}`}function PV($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=n7(Z);return{description:Y.description||J,command:Y.command}}function p0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
126
119
  ${$}
127
- ${J}`}function f$($,Z=iL,J=""){if($.length<=Z)return i0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,i0(`${Y}
120
+ ${J}`}function y$($,Z=qL,J=""){if($.length<=Z)return p0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,p0(`${Y}
128
121
  ... output 已截断 ...`,J)].join(`
129
- `)}function m($){return"`"+String($??"").replace(/`/g,"'")+"`"}function Y$($,Z=3000){return i0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function H9($){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 eV($,Z,J){let Y=tV($),Q=Y.command,V=Y.description,H=[];if(V)H.push(`**目的**: ${V}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${m(X)}`);if($?.source)H.push(`**source**: ${m($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(i0(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(f$(Z));return H.join(`
130
- `)}function $H($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${sV($)}`),Q!==void 0)Y.push(`**session**: ${m(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(i0(V))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(f$(Z));return Y.join(`
131
- `)}function ZH($){return Array.isArray($?.changes)?$.changes:[]}function JH($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function Y9($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&b5(J)&&b5(Z)){let Y=dL(Z,J);if(Y&&!Y.startsWith("..")&&!b5(Y))return Y}return J}function sL($){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 YH($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function k5($){let Z=sL($);if(YH($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function y5($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function w5($){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 QH($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function v5($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function tL($){return $.length>1800?$.slice(0,1800)+`
132
- ... diff 已截断 ...`:$}function eL($){let Z=ZH($),J=JH($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",W=$?.grantRoot?Y9($.grantRoot):"";if(z&&W)return`${z} · ${W}`;return z||(W?`申请修改 ${W}`:"")}let Y=Z.map((z)=>w5(y5(z))).reduce(QH,{added:0,removed:0}),Q=v5(Y),V=[...new Set(Z.map(k5))],H=Y9(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${V[0]} ${H}${X}`;return`${Z.length} 个文件 · ${V.join("/")} · ${H} 等${X}`}function VH($,Z,J){let Y=ZH($),Q=JH($),V=[];if(Y.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"";if(W)V.push(`**原因**: ${W}`);if($?.grantRoot)V.push(`**范围**: ${m(Y9($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(i0(Z.slice(0,3000)));return V.length>0?V.join(`
133
- `):i0(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((W)=>w5(y5(W))).reduce(QH,{added:0,removed:0}),X=v5(H);if(V.push(`**文件**: ${Y.length} 个`),X)V.push(`**行数**: ${X}`);if($?.status)V.push(`**状态**: ${m($.status)}`);let z=Y.slice(0,5);for(let W of z){let G=y5(W),B=v5(w5(G)),_=Y9(W?.path,Q),j=B?`**${k5(W)}** ${m(_)} · ${B}`:`**${k5(W)}** ${m(_)}`;V.push(""),V.push(j);let q=YH(W);if(q)V.push(`来自 ${m(Y9(q,Q))}`);V.push(G?i0(tL(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(`
134
- `)}function V1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function $q($){let Z=V1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function Zq($){let Z=V1($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function Jq($){let Z=V1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function Yq($){let Z=V1($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function Qq($,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 HH($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function Vq($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let V=HH(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 Hq($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function h2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(f$(Z,1200))}function XH($,Z,J){let Y=[],Q=V1($);if(Q)Y.push(`**路径**: ${m(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${m($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${m($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
135
- `):Y$($??{},2000)}function zH($,Z,J){let Y=[],Q=V1($),V=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${m(Q)}`);if(V){let H=V.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${V.length} 字符`),Y.push(f$(V,1200))}if(J)Y.push(""),Y.push(J);return h2(Y,Z),Y.length>0?Y.join(`
136
- `):Y$($??{},2000)}function WH($,Z,J){let Y=[],Q=V1($);if(Q)Y.push(`**路径**: ${m(Q)}`);if($?.cell_id)Y.push(`**cell**: ${m($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${m($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(f$($.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(f$(V,800));if(J)Y.push(""),Y.push(J);return h2(Y,Z),Y.length>0?Y.join(`
137
- `):Y$($??{},2000)}function GH($,Z,J){let Y=[],Q=V1($),V=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${m(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(f$(X.old_string,500));if(typeof X?.new_string==="string")Y.push("替换为:"),Y.push(f$(X.new_string,500))}if(V.length>5)Y.push(""),Y.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return h2(Y,Z),Y.join(`
138
- `)}function KH($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${m(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${m(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${m(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${m(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${m(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${m(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${m(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${m(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(m).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return h2(Q,J),Q.join(`
139
- `)}function BH($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let V of Y.slice(0,12)){let H=HH(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 h2(Q,Z),Q.join(`
140
- `)}function g5($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function m5($,Z){return g5(Z)??$?.action??{}}function p5($,Z){let J=m5($,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 c5($,Z){let J=m5($,Z);return String(J?.url??$?.url??"")}function _H($){let Z=p5($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=c5($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function Xq($,Z){let J=p5($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=c5($,Z);if(Y)return Y;return _H($)}function jH($,Z,J){let Y=m5($,Z),Q=p5($,Z),V=c5($,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(`- ${m(z)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(X==="open_page"){if(H.push("**动作**: 打开页面"),V)H.push(`**URL**: ${m(V)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),V)H.push(`**URL**: ${m(V)}`);if(Y?.pattern)H.push(`**关键词**: ${m(Y.pattern)}`)}else if(H.push(`**动作**: ${X?m(X):"网页搜索"}`),V)H.push(`**URL**: ${m(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(i0(Z.slice(0,3000),"json"));return H.join(`
141
- `)}function LH($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${m($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return h2(Y,Z),Y.join(`
142
- `)}function zq($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=H9($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function qH($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${m($.server)}`);if($?.tool)Y.push(`**tool**: ${m($.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(Y$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let V=g5(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(`
143
- `).slice(0,3000));if(V.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(Y$(V.structuredContent,2000));if(H.length===0&&!V.structuredContent)Y.push(Y$(V,3000))}else Y.push(V?Y$(V,3000):i0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
144
- `):Y$($??{},2000)}function Wq($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${m(typeof Z?.tool==="string"&&Z.tool?Z.tool:rV($))}`],V=Z?.input;if(V&&typeof V==="object")if(Q.push(""),Q.push("**input**"),Object.keys(V).length>0)Q.push(Y$(V,2000));else Q.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Q.push(`**input**: ${m(V)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(f$(J,3000));return Q.join(`
145
- `)}function Gq($){return typeof $?.status==="string"?$.status:""}function PH($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${m($.status)}`);if($?.prompt)Q.push("","**提示词**",i0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",i0(String($.revisedPrompt)))}if(J)Q.push(""),Q.push(J);if(!Y&&Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(m(Z.trim()));return Q.length>0?Q.join(`
146
- `):Y$($??{},2000)}function Kq($){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 r8($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${m($.tool)}`);if($?.model)Y.push(`**model**: ${m($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${m($.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=g5(Z);Y.push(Q?Y$(Q,3000):i0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
147
- `):Y$($??{},2000)}function R$($,Z,J,Y,Q="⏳",V,H){let X=Q9(Z)&&Y!=null?Xq(J,Y):Q1(Z,J),z=X.length>80?X.slice(0,80)+"…":X,W=f1(Z),G=z?`${Q} \uD83D\uDD27 ${W}: ${z}`:`${Q} \uD83D\uDD27 ${W}`,B=V?`
148
-
149
- ${V}`:"",_=s8(Z)?eV(J,Y,V):t8(Z)?$H(J,Y,V):X6(Z)?Wq(Z,J,Y,V):e8(Z)?VH(J,Y,V):Q9(Z)?jH(J,Y,V):$6(Z)?LH(J,Y,V):f5(Z)?qH(J,Y,V):V9(Z)?PH(J,Y,V,H):Z6(Z)?XH(J,Y,V):J6(Z)?zH(J,Y,V):Y6(Z)?WH(J,Y,V):Q6(Z)?GH(J,Y,V):I5(Z)?KH(Z,J,Y,V):V6(Z)?BH(J,Y,V):H6(Z)?r8({prompt:H9(J)||"提交计划"},Y,V):h5(Z)?r8(J,Y,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+B+(Y!=null?`
122
+ `)}function m($){return"`"+String($??"").replace(/`/g,"'")+"`"}function s0($,Z=3000){return p0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function c4($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Y=Z[J];if(typeof Y==="string"&&Y.length>0)return Y}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function DV($,Z,J){let Y=PV($),Q=Y.command,V=Y.description,H=[];if(V)H.push(`**目的**: ${V}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${m(X)}`);if($?.source)H.push(`**source**: ${m($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(p0(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(`
123
+ `)}function FV($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${qV($)}`),Q!==void 0)Y.push(`**session**: ${m(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(p0(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(`
124
+ `)}function MV($){return Array.isArray($?.changes)?$.changes:[]}function UV($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function g4($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&i3(J)&&i3(Z)){let Y=LL(Z,J);if(Y&&!Y.startsWith("..")&&!i3(Y))return Y}return J}function UL($){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 AV($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function a3($){let Z=UL($);if(AV($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function o3($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function r3($){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 OV($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function s3($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function AL($){return $.length>1800?$.slice(0,1800)+`
125
+ ... diff 已截断 ...`:$}function OL($){let Z=MV($),J=UV($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",W=$?.grantRoot?g4($.grantRoot):"";if(z&&W)return`${z} · ${W}`;return z||(W?`申请修改 ${W}`:"")}let Y=Z.map((z)=>r3(o3(z))).reduce(OV,{added:0,removed:0}),Q=s3(Y),V=[...new Set(Z.map(a3))],H=g4(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${V[0]} ${H}${X}`;return`${Z.length} 个文件 · ${V.join("/")} · ${H} 等${X}`}function RV($,Z,J){let Y=MV($),Q=UV($),V=[];if(Y.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"";if(W)V.push(`**原因**: ${W}`);if($?.grantRoot)V.push(`**范围**: ${m(g4($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(p0(Z.slice(0,3000)));return V.length>0?V.join(`
126
+ `):p0(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((W)=>r3(o3(W))).reduce(OV,{added:0,removed:0}),X=s3(H);if(V.push(`**文件**: ${Y.length} 个`),X)V.push(`**行数**: ${X}`);if($?.status)V.push(`**状态**: ${m($.status)}`);let z=Y.slice(0,5);for(let W of z){let G=o3(W),B=s3(r3(G)),_=g4(W?.path,Q),j=B?`**${a3(W)}** ${m(_)} · ${B}`:`**${a3(W)}** ${m(_)}`;V.push(""),V.push(j);let q=AV(W);if(q)V.push(`来自 ${m(g4(q,Q))}`);V.push(G?p0(AL(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(`
127
+ `)}function s$($){return String($?.file_path??$?.path??$?.notebook_path??"")}function RL($){let Z=s$($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function NL($){let Z=s$($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function TL($){let Z=s$($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function EL($){let Z=s$($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function xL($,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 NV($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function SL($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let V=NV(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 CL($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function R2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(y$(Z,1200))}function TV($,Z,J){let Y=[],Q=s$($);if(Q)Y.push(`**路径**: ${m(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${m($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${m($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
128
+ `):s0($??{},2000)}function EV($,Z,J){let Y=[],Q=s$($),V=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${m(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 R2(Y,Z),Y.length>0?Y.join(`
129
+ `):s0($??{},2000)}function xV($,Z,J){let Y=[],Q=s$($);if(Q)Y.push(`**路径**: ${m(Q)}`);if($?.cell_id)Y.push(`**cell**: ${m($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${m($.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 R2(Y,Z),Y.length>0?Y.join(`
130
+ `):s0($??{},2000)}function SV($,Z,J){let Y=[],Q=s$($),V=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${m(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 R2(Y,Z),Y.join(`
131
+ `)}function CV($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${m(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${m(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${m(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${m(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${m(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${m(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${m(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${m(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(m).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return R2(Q,J),Q.join(`
132
+ `)}function bV($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let V of Y.slice(0,12)){let H=NV(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 R2(Q,Z),Q.join(`
133
+ `)}function Z5($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function J5($,Z){return Z5(Z)??$?.action??{}}function Y5($,Z){let J=J5($,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 Q5($,Z){let J=J5($,Z);return String(J?.url??$?.url??"")}function kV($){let Z=Y5($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=Q5($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function bL($,Z){let J=Y5($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=Q5($,Z);if(Y)return Y;return kV($)}function yV($,Z,J){let Y=J5($,Z),Q=Y5($,Z),V=Q5($,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(`- ${m(z)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(X==="open_page"){if(H.push("**动作**: 打开页面"),V)H.push(`**URL**: ${m(V)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),V)H.push(`**URL**: ${m(V)}`);if(Y?.pattern)H.push(`**关键词**: ${m(Y.pattern)}`)}else if(H.push(`**动作**: ${X?m(X):"网页搜索"}`),V)H.push(`**URL**: ${m(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(p0(Z.slice(0,3000),"json"));return H.join(`
134
+ `)}function vV($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${m($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return R2(Y,Z),Y.join(`
135
+ `)}function kL($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=c4($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function wV($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${m($.server)}`);if($?.tool)Y.push(`**tool**: ${m($.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(s0(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let V=Z5(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(`
136
+ `).slice(0,3000));if(V.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(s0(V.structuredContent,2000));if(H.length===0&&!V.structuredContent)Y.push(s0(V,3000))}else Y.push(V?s0(V,3000):p0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
137
+ `):s0($??{},2000)}function yL($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${m(typeof Z?.tool==="string"&&Z.tool?Z.tool:LV($))}`],V=Z?.input;if(V&&typeof V==="object")if(Q.push(""),Q.push("**input**"),Object.keys(V).length>0)Q.push(s0(V,2000));else Q.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Q.push(`**input**: ${m(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(`
138
+ `)}function vL($){return typeof $?.status==="string"?$.status:""}function fV($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${m($.status)}`);if($?.prompt)Q.push("","**提示词**",p0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",p0(String($.revisedPrompt)))}if(J)Q.push(""),Q.push(J);if(!Y&&Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(m(Z.trim()));return Q.length>0?Q.join(`
139
+ `):s0($??{},2000)}function wL($){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 b8($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${m($.tool)}`);if($?.model)Y.push(`**model**: ${m($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${m($.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=Z5(Z);Y.push(Q?s0(Q,3000):p0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
140
+ `):s0($??{},2000)}function F$($,Z,J,Y,Q="⏳",V,H){let X=m4(Z)&&Y!=null?bL(J,Y):r$(Z,J),z=X.length>80?X.slice(0,80)+"…":X,W=O1(Z),G=z?`${Q} \uD83D\uDD27 ${W}: ${z}`:`${Q} \uD83D\uDD27 ${W}`,B=V?`
141
+
142
+ ${V}`:"",_=k8(Z)?DV(J,Y,V):y8(Z)?FV(J,Y,V):c8(Z)?yL(Z,J,Y,V):v8(Z)?RV(J,Y,V):m4(Z)?yV(J,Y,V):w8(Z)?vV(J,Y,V):t3(Z)?wV(J,Y,V):p4(Z)?fV(J,Y,V,H):f8(Z)?TV(J,Y,V):h8(Z)?EV(J,Y,V):I8(Z)?xV(J,Y,V):g8(Z)?SV(J,Y,V):$5(Z)?CV(Z,J,Y,V):m8(Z)?bV(J,Y,V):p8(Z)?b8({prompt:c4(J)||"提交计划"},Y,V):e3(Z)?b8(J,Y,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+B+(Y!=null?`
150
143
  ---
151
144
  **output:**
152
145
  \`\`\`
153
- `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:N.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:Z0(_)},...V9(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function X9($,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=aV(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((z)=>{let W=aV(z);return W?`\`${W}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:N.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:Z0(X.join(`
154
- `))}]}}function aV($){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 z9($,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=Q1("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:N.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:Z0(X.join(`
155
- `))}]}}function u5($,Z,J,Y){let Q=Q1(Z,J),V=f1(Z),H=Q?`\uD83D\uDD10 等审批 · ${V}: ${Q}`:`\uD83D\uDD10 等审批 · ${V}`,X=s8(Z)?eV(J,null):t8(Z)?$H(J,null):e8(Z)?VH(J,null):Q9(Z)?jH(J,null):$6(Z)?LH(J,null):f5(Z)?qH(J,null):V9(Z)?PH(J,null):Z6(Z)?XH(J,null):J6(Z)?zH(J,null):Y6(Z)?WH(J,null):Q6(Z)?GH(J,null):I5(Z)?KH(Z,J,null):V6(Z)?BH(J,null):H6(Z)?r8({prompt:H9(J)||"提交计划"},null):h5(Z)?r8(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:N.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[C5("✅ 允许","primary",Y,"allow"),C5("♾️ 始终允许","default",Y,"allow_always"),C5("❌ 拒绝","danger",Y,"deny")]}]}}function C5($,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 iL=300,oV="server_tool:";var DH=O(()=>{b0();s9()});import{execFile as Bq}from"node:child_process";import{readFileSync as l5,statfsSync as _q,statSync as FH}from"node:fs";import{cpus as jq,homedir as Lq}from"node:os";import{promisify as qq}from"node:util";function Dq(){try{let $=l5("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:jq().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return K(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function Fq(){try{let $=l5("/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 UH($,Z){try{let J=_q(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 Uq(){let $=[],Z=UH("/","/");if(Z)$.push(Z);let J=Lq();if(J&&J!=="/"){let Y=!1;try{let Q=FH("/"),V=FH(J);Y=Q.dev===V.dev}catch{}if(!Y){let Q=UH("$HOME",J);if(Q)$.push(Q)}}return $}function Mq(){try{let $=l5("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function MH($,Z=2000){try{let{stdout:J}=await Pq("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return K(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function AH($){return OH.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function Aq(){let $=await MH(["list-units","--type=service","--all","--no-legend","--plain",...OH.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
156
- `).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(!AH(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await MH(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=Mq(),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(`
157
- `)){let _=B.indexOf("=");if(_<=0)continue;W[B.slice(0,_)]=B.slice(_+1)}let G=W.Id??"";if(!AH(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 RH(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=Dq(),Z=Fq(),J=Uq(),{services:Y,error:Q}=await Aq();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var Pq,OH,W9="cc-* / codex-*";var d5=O(()=>{f();Pq=qq(Bq),OH=["cc-","codex-"]});function K9($,Z){return Z}function i5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:N.footer,content:K9($.title,$.status)}]}}}function NH($){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 Oq($){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 G9($){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 Eq($){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 xq($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${W9} _n/a_`].join(`
158
- `);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}% (${NH($.mem.usedBytes)}/${NH($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${W9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${W9} _无_`);else{Z.push(`**服务** ${W9} (${$.services.length})`);for(let J of $.services){let Y=Tq[J.active]??"·",Q=J.lastActiveAgoSec,V=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(V!=null)H.push(`已运行 ${G9(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${G9(Q*1000)}前`);else H.push("从未启动");if(V!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${G9(V*1000)}`)}}else if(V!=null)H.push(`已 ${G9(V*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
159
- `)}function Sq($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=Rq[J.status]??"·",Q=Nq[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${G9(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"",X=J.codexAccountName===void 0?"":` · Codex:${H1(W$(J.codexAccountName))}`;return` · ${Y} \`${J.name}\` · ${Q}${V}${H}${X}`}).join(`
160
- `)}function z6($,Z=N.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:Sq($)}]}}function bq($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${t5($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
161
- `)}function W6($,Z=N.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:bq($)}}function G6($,Z=N.consoleHost){let J=Eq($);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:xq($)}]}}function K6($){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(Cq).join(" · ")}`}function Cq($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function kq($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.flatMap((Y)=>T2(Y,Y.label).map((Q)=>Q.content))].join(`
162
- `):K6($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=TH($);return J?`${Z}
163
- ${J}`:Z}function TH($){return $?.resetCredits===void 0?"":`**重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`}function B9($){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(...T2(Q,Q.label))}let Y=TH(Z);if(Y)J.push({tag:"hr"},{tag:"markdown",content:Y});return{tag:"collapsible_panel",element_id:N.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:N.consoleUsage,content:kq(Z)}}function EH($,Z){return[W6($,Z),z6($),G6($.sysinfo),B9($)]}function n5($){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:EH($)}}}function a5($){return I2($.sessionName,{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${H1($.currentDisplay??"未选择")}
164
- 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:N.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)=>yq(Y,$.panelId))}]:[]})]})}function yq($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${W$($.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:`**${W$($.display)}**
165
- ${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 o5($){return I2($.sessionName,xH($))}function r5($){return I2($.sessionName,j6($))}function B6($){return I2($.sessionName,L6($),"green")}function I2($,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=fq($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${SH($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
166
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?wq($.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 wq($,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 _6($,Z="cancelled"){return I2($,{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function s5($,Z,J){return I2($,{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
167
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function g2($,Z,J){return{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
168
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function j6($){return{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${gq($.model)}`,`当前: ${SH($.currentModel,$.currentEffort)}`].join(`
169
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>hq($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function L6($){return{tag:"collapsible_panel",element_id:N.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",H1(bH($.model,$.effort,$.provider)),W$($.scope)].join(`
170
- `)}]}}function vq($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${W$($.displayName)}** · 未配置
171
- ${W$($.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?`**${W$($.displayName)}**`:`**${H1($.model)}**`,V=[$.isDefault?`${t5($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
172
- `+W$(mq($.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?H1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
173
- `)+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:Iq($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?X("model_custom_remove","删"):X("model_remove","隐")]:[]]}]}]}function fq($,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"}]:[],...vq(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 hq($,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"?"模型默认":W$(Z.effort)}**`,H,Z.description?W$(Z.description):""].filter(Boolean).join(`
174
- `)}]},{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 Iq($,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 gq($){return $.displayName&&$.displayName!==$.model?`${W$($.displayName)} (${H1($.model)})`:H1($.model)}function SH($,Z){return H1(bH($,Z))}function bH($,Z,J){let Y=J&&J!=="codex"?`${t5(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function t5($){return j$($??"codex")}function mq($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function W$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function H1($){return"`"+$.replace(/`/g,"\\`")+"`"}function h$($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${G0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${Oq($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var Rq,Nq,Tq;var CH=O(()=>{_0();d5();b0();Rq={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},Nq={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},Tq={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function e5($){let Z=uq($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:pq($.notice)},body:{elements:[...$.notice?[cq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(lq)]}}}function pq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function cq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
146
+ `+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:Z0(_)},...p4(Z)&&H?[{tag:"img",img_key:H,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function u4($,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=_V(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((z)=>{let W=_V(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:Z0(X.join(`
147
+ `))}]}}function _V($){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 l4($,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=r$("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:Z0(X.join(`
148
+ `))}]}}function V5($,Z,J,Y){let Q=r$(Z,J),V=O1(Z),H=Q?`\uD83D\uDD10 等审批 · ${V}: ${Q}`:`\uD83D\uDD10 等审批 · ${V}`,X=k8(Z)?DV(J,null):y8(Z)?FV(J,null):v8(Z)?RV(J,null):m4(Z)?yV(J,null):w8(Z)?vV(J,null):t3(Z)?wV(J,null):p4(Z)?fV(J,null):f8(Z)?TV(J,null):h8(Z)?EV(J,null):I8(Z)?xV(J,null):g8(Z)?SV(J,null):$5(Z)?CV(Z,J,null):m8(Z)?bV(J,null):p8(Z)?b8({prompt:c4(J)||"提交计划"},null):e3(Z)?b8(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:[n3("✅ 允许","primary",Y,"allow"),n3("♾️ 始终允许","default",Y,"allow_always"),n3("❌ 拒绝","danger",Y,"deny")]}]}}function n3($,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 qL=300,jV="server_tool:";var hV=O(()=>{S0();o9()});import{execFile as fL}from"node:child_process";import{readFileSync as H5,statfsSync as hL,statSync as IV}from"node:fs";import{cpus as IL,homedir as gL}from"node:os";import{promisify as mL}from"node:util";function cL(){try{let $=H5("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:IL().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return K(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function uL(){try{let $=H5("/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 gV($,Z){try{let J=hL(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 lL(){let $=[],Z=gV("/","/");if(Z)$.push(Z);let J=gL();if(J&&J!=="/"){let Y=!1;try{let Q=IV("/"),V=IV(J);Y=Q.dev===V.dev}catch{}if(!Y){let Q=gV("$HOME",J);if(Q)$.push(Q)}}return $}function dL(){try{let $=H5("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function mV($,Z=2000){try{let{stdout:J}=await pL("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return K(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function pV($){return cV.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function iL(){let $=await mV(["list-units","--type=service","--all","--no-legend","--plain",...cV.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
149
+ `).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(!pV(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await mV(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=dL(),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(`
150
+ `)){let _=B.indexOf("=");if(_<=0)continue;W[B.slice(0,_)]=B.slice(_+1)}let G=W.Id??"";if(!pV(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 uV(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=cL(),Z=uL(),J=lL(),{services:Y,error:Q}=await iL();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var pL,cV,d4="cc-* / codex-*";var X5=O(()=>{f();pL=mL(fL),cV=["cc-","codex-"]});function N2($){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 T2($,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())?`${N2($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Q)}%${Y}**
151
+ <font color='${H}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${X}</font>`,text_size:"notation"}]}function n4($,Z){return Z}function z5($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:R.footer,content:n4($.title,$.status)}]}}}function lV($){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 nL($){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 i4($){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 sL($){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 tL($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${d4} _n/a_`].join(`
152
+ `);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}% (${lV($.mem.usedBytes)}/${lV($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${d4} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${d4} _无_`);else{Z.push(`**服务** ${d4} (${$.services.length})`);for(let J of $.services){let Y=rL[J.active]??"·",Q=J.lastActiveAgoSec,V=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(V!=null)H.push(`已运行 ${i4(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${i4(Q*1000)}前`);else H.push("从未启动");if(V!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${i4(V*1000)}`)}}else if(V!=null)H.push(`已 ${i4(V*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
153
+ `)}function eL($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=aL[J.status]??"·",Q=oL[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${i4(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"",X=J.codexAccountName===void 0?"":` · Codex:${t$(V$(J.codexAccountName))}`;return` · ${Y} \`${J.name}\` · ${Q}${V}${H}${X}`}).join(`
154
+ `)}function u8($,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:eL($)}]}}function $q($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${j5($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
155
+ `)}function l8($,Z=R.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:$q($)}}function d8($,Z=R.consoleHost){let J=sL($);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:tL($)}]}}function i8($){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(Zq).join(" · ")}`}function Zq($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function Jq($){let Z=$?.state==="ok"&&$.kind!=="balance"&&!$.quota&&$.windows.length?["**\uD83D\uDCCA 额度**",...$.windows.flatMap((Y)=>T2(Y,Y.label).map((Q)=>Q.content))].join(`
156
+ `):i8($).replace(/^(额度|余额)/,"**\uD83D\uDCCA $1**"),J=dV($);return J?`${Z}
157
+ ${J}`:Z}function dV($){return $?.resetCredits===void 0?"":`**重置卡** ${$.resetCredits===null?"MISS":`${$.resetCredits} 次可用`}`}function a4($){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(...T2(Q,Q.label))}let Y=dV(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:Jq(Z)}}function iV($,Z){return[l8($,Z),u8($),d8($.sysinfo),a4($)]}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:iV($)}}}function G5($){return E2($.sessionName,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${t$($.currentDisplay??"未选择")}
158
+ 选账号进入模型选择。`},...["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)=>Yq(Y,$.panelId))}]:[]})]})}function Yq($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${V$($.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:`**${V$($.display)}**
159
+ ${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 K5($){return E2($.sessionName,nV($))}function B5($){return E2($.sessionName,o8($))}function n8($){return E2($.sessionName,r8($),"green")}function E2($,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 nV($){let Z=Hq($.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:[`当前: ${aV($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
160
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?Qq($.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 Qq($,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 a8($,Z="cancelled"){return E2($,{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function _5($,Z,J){return E2($,{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(`
161
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function x2($,Z,J){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
162
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function o8($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${Wq($.model)}`,`当前: ${aV($.currentModel,$.currentEffort)}`].join(`
163
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>Xq($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function r8($){return{tag:"collapsible_panel",element_id:R.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",t$(oV($.model,$.effort,$.provider)),V$($.scope)].join(`
164
+ `)}]}}function Vq($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${V$($.displayName)}** · 未配置
165
+ ${V$($.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?`**${V$($.displayName)}**`:`**${t$($.model)}**`,V=[$.isDefault?`${j5($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),H=$.description?`
166
+ `+V$(Gq($.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?t$($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
167
+ `)+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:zq($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?X("model_custom_remove","删"):X("model_remove","隐")]:[]]}]}]}function Hq($,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"}]:[],...Vq(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 Xq($,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"?"模型默认":V$(Z.effort)}**`,H,Z.description?V$(Z.description):""].filter(Boolean).join(`
168
+ `)}]},{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 zq($,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 Wq($){return $.displayName&&$.displayName!==$.model?`${V$($.displayName)} (${t$($.model)})`:t$($.model)}function aV($,Z){return t$(oV($,Z))}function oV($,Z,J){let Y=J&&J!=="codex"?`${j5(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function j5($){return L$($??"codex")}function Gq($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function V$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function t$($){return"`"+$.replace(/`/g,"\\`")+"`"}function R1($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${F0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${nL($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var aL,oL,rL;var rV=O(()=>{B0();X5();S0();aL={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},oL={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},rL={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function L5($){let Z=_q($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:Kq($.notice)},body:{elements:[...$.notice?[Bq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(jq)]}}}function Kq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function Bq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
175
169
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
176
- `)}}function uq($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${q6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function lq($){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:`**${q6($.slug)}**
170
+ `)}}function _q($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${s8("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function jq($){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:`**${s8($.slug)}**
177
171
  ${Z} · ${J}
178
- ${q6($.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 _9($){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,q6($.branch),...$.body?[$.body]:[]].join(`
179
- `)}]}}}function q6($){return"`"+$.replace(/`/g,"\\`")+"`"}function ZZ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
172
+ ${s8($.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 o4($){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,s8($.branch),...$.body?[$.body]:[]].join(`
173
+ `)}]}}}function s8($){return"`"+$.replace(/`/g,"\\`")+"`"}function P5($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
180
174
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
181
- 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:dq($.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:`**${VZ(H.ts)}**
182
- ${X1(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 JZ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
183
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${VZ(J.ts)}**
184
- ${X1(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 YZ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
175
+ 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:Lq($.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:`**${U5(H.ts)}**
176
+ ${e$(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 D5($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
177
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${U5(J.ts)}**
178
+ ${e$(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 F5($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
185
179
  …(截断)`:J.body;return`${J.path} (${J.tool})
186
180
  ${Y}`}).join(`
187
181
 
188
- `);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 z1($){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?"✅":"❌"} ${$Z($.message)}`}]}}}function QZ($){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?` · 状态 ${X1($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${X1(P6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
182
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function $1($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${q5($.message)}`}]}}}function M5($){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?` · 状态 ${e$($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${e$(t8($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
189
183
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
190
- `):$.bindingState==="unchanged"?[`${$Z($.message)}`,"",`本群原绑定 ${X1(P6($.previousSessionId))};源会话未修改。`].join(`
191
- `):[`${$Z($.message)}`,"",`后端返回会话 ${X1(P6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
192
- `);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}**`,`**${VZ($.selectedTs)}**${V}`,X1(Q),`源会话 ${X1(P6($.sourceSessionId))}`].join(`
193
- `)},{tag:"markdown",content:H}]}}}function VZ($){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 X1($){return"`"+kH($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function P6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function $Z($){return kH($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function kH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function dq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
184
+ `):$.bindingState==="unchanged"?[`${q5($.message)}`,"",`本群原绑定 ${e$(t8($.previousSessionId))};源会话未修改。`].join(`
185
+ `):[`${q5($.message)}`,"",`后端返回会话 ${e$(t8($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
186
+ `);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}**`,`**${U5($.selectedTs)}**${V}`,e$(Q),`源会话 ${e$(t8($.sourceSessionId))}`].join(`
187
+ `)},{tag:"markdown",content:H}]}}}function U5($){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 e$($){return"`"+sV($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function t8($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function q5($){return sV($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function sV($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Lq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
194
188
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
195
- `)}function yH($){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(`
189
+ `)}function tV($){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(`
196
190
  ---
197
- `);return""}function HZ($,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:yH(Z)}]}function zZ($){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?[aq($.notice)]:[],{tag:"markdown",element_id:N.tasklistPanel,content:iq($)},nq($)]}}}function iq($){let Z=[`项目:${XZ($.projectName)}`,`清单:${XZ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
198
- `);if(Z.push("","已启用"),Z.push(`GUID:${XZ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
199
- `)}function nq($){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 aq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
200
- `).map((J)=>`<font color='${Z}'>${oq(J)||" "}</font>`).join(`
201
- `)}}function XZ($){return"`"+$.replace(/`/g,"\\`")+"`"}function oq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var wH=O(()=>{b0()});import{createHash as rq}from"node:crypto";function GZ($){let Z=[{tag:"markdown",element_id:N.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
202
- `)}];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)=>`- **${N$(J.display)}**:${N$(J.reason)}`).join(`
203
- `)}]});return Z.push(...$.catalog.map(eq),$P($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function KZ($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!_Z($.status),summary:{content:D6($)}},body:{elements:[j9($)]}}}function j9($){return{tag:"collapsible_panel",element_id:L9($.runId),header:{title:{tag:"plain_text",content:D6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${N$($.description??"说明 MISS")}**`,IH($).content,`**任务说明**
204
- ${JP($.prompt)}`,...$.workers.map((Z)=>hH(Z,gH($.workers.length)).content)].join(`
205
-
206
- `)}]}}function L9($){return`ar_${rq("sha256").update($).digest("hex").slice(0,16)}`}function BZ($){if($.length===1)return D6($[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 hH($,Z=fH){let J=ZP($),Y=[`模型 ${h1($.model)} · 推理 ${h1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${G0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",N$($.queuedReason));if($.pendingInput){Y.push("","**等待主 Agent 回答**");for(let Q of $.pendingInput.questions)if(Y.push(`- ${N$(Q.question)}`),Q.options.length)Y.push(` 选项:${Q.options.map((V)=>h1(V.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",Z0($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",YP(Z0($.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} ${h1(H)} ${N$(pH(Q.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${N$($.identityName)}**`,...Y].join(`
207
- `)}}function IH($){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:[`**${mH($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${G0(z/1000)}`]:[],...$.error?[N$($.error)]:[]].join(`
208
- `)}}function gH($){let Z=Math.max(1,Math.floor($));return Math.min(fH,Math.max(tq,Math.floor(sq/Z)))}function D6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${mH($)} · ${pH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function eq($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${N$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${h1($.id)}
209
- ${h1($.model)} · 默认 ${h1($.defaultEffort??"MISS")} · ${N$(J)}`].join(`
210
- `)}}function $P($){return{tag:"column_set",columns:[WZ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),WZ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),WZ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function WZ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function ZP($){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 mH($){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 JP($){let Z=Z0($);if(Z.length<=vH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,vH-J.length-2)}
211
-
212
- ${J}`}function YP($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
213
-
214
- ${J}`}function h1($){return"`"+$.replace(/`/g,"\\`")+"`"}function N$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function pH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var vH=1e4,sq=48000,fH=8000,tq=512;var cH=O(()=>{b0()});function g1($){return QP.has($)?$:null}function F6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function m2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function I1($){return String($?.subject??$?.content??"").trim()}function jZ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function dH($){return`subj:${$}`}function uH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function zP($){let Z=I1($);if(!Z)return null;return{id:m2($)||dH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:jZ($)??"pending"}}function LZ($,Z,J,Y){if(Z==="TaskList"){let Q=F6(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=zP(X);if(z)H.push(z)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let W=F6(Y),G=Array.isArray(W?.tasks)?W.tasks:Array.isArray(W)?W:null,B=$;return Q.forEach((_,j)=>{let q=I1(_);if(!q)return;let P=G?.[j],D=P&&m2(P)||uH(Y??"");B=lH(B,D,q,_)}),B}let V=F6(Y),H=V?.task??V,X=m2(H)||uH(Y??""),z=I1(H)||I1(J);if(!z)return $;return lH($,X,z,J)}if(Z==="TaskUpdate"){let Q=m2(J);if(!Q)return $;let V=jZ(J);if(V==="deleted")return $.filter((X)=>X.id!==Q);let H=I1(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=F6(Y),V=Q?.task??Q,H=m2(V)||m2(J);if(!H)return $;let X=$.find((G)=>G.id===H),z=I1(V)||X?.subject||I1(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:jZ(V)??X?.status??"pending"};return X?$.map((G)=>G.id===H?W:G):[...$,W]}return $}function lH($,Z,J,Y){let Q=Z||dH(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 qZ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let H=HP[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 iH($,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=XP[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(`
215
- `)}function W1($,Z,J,Y){let Q=VP[J.name],V=qZ(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${V}`;return{tag:"collapsible_panel",element_id:N.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:iH(Z,Y)}]}}function m1($){return{tag:"collapsible_panel",element_id:N.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${qZ($)}`}},expanded:!0,elements:[{tag:"markdown",content:iH($)}]}}var QP,VP,HP,XP;var nH=O(()=>{b0();QP=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);VP={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},HP={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},XP={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var Q$=O(()=>{b0();u8();nV();DH();CH();wH();cH();nH();j3()});import{readFileSync as WP}from"node:fs";import{homedir as GP}from"node:os";import{join as sH}from"node:path";function KP(){return process.env.CLAUDE_CONFIG_DIR||sH(GP(),".claude")}function DZ(){try{let $=WP(sH(KP(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return K(`glm-usage: read settings.json env failed: ${$}`),{}}}function p1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function BP($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function _P($){let Z=BP($);return Z&&p1($)?Z:null}function oH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function rH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function jP($){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:oH(G.percentage),resetsAt:rH(G.nextResetTime)}:null,X=H(Y),z=H(Q),W=V?{percent:oH(V.percentage),resetsAt:rH(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 q9($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:DZ(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let V=_P(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(),aH);try{let W=await $0(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 jP(B)}catch(W){let G=W?.name==="AbortError"?`timeout ${aH}ms`:W?.message??String(W);return K(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(z)}}async function tH(){if(p2)return p2;return p2=q9().then(($)=>{if(p2=null,$.state==="network")return PZ??$;return PZ=$,$}).catch(($)=>{return K(`glm-usage: fetchGlmUsage threw: ${$}`),p2=null,PZ??{state:"network",reason:String($)}}),p2}var aH=1e4,PZ=null,p2=null;var P9=O(()=>{h0();f()});function eH($){let Z=[];for(let J of $.matchAll(LP)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function U6($,Z=process.platform){if(Z!=="win32")return $;let J=qP.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var LP,qP;var FZ=O(()=>{LP=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;qP=/^\/([a-zA-Z])\//});function JX($){if($X.test($))return{marker:"start",body:$.replace($X,"")};if(ZX.test($))return{marker:"end",body:$.replace(ZX,"")};return{marker:"none",body:$}}var $X,ZX;var YX=O(()=>{$X=/^>{3,}[ \t]?/,ZX=/^<{3,}[ \t]?/});async function QX($,Z,J,Y,Q){let{marker:V,body:H}=JX(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)MZ($,"reopen");return $.multiMsgBuffer=[],UZ($,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}UZ($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await DP($,X,z),!0}if($.multiMsgBuffer!==null)return UZ($,Z,J,Y,Q),!0;return!1}function UZ($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)PP($,Q)}function PP($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await l0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else k0(Z,J)})()}async function DP($,Z,J){for(let[H,X]of J)if(X)k0(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(" ")+`
191
+ `);return""}function A5($,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:tV(Z)}]}function R5($){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?[Dq($.notice)]:[],{tag:"markdown",element_id:R.tasklistPanel,content:qq($)},Pq($)]}}}function qq($){let Z=[`项目:${O5($.projectName)}`,`清单:${O5($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
192
+ `);if(Z.push("","已启用"),Z.push(`GUID:${O5($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
193
+ `)}function Pq($){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 Dq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
194
+ `).map((J)=>`<font color='${Z}'>${Fq(J)||" "}</font>`).join(`
195
+ `)}}function O5($){return"`"+$.replace(/`/g,"\\`")+"`"}function Fq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var eV=O(()=>{S0()});import{createHash as Mq}from"node:crypto";function T5($){let Z=[{tag:"markdown",element_id:R.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
196
+ `)}];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)=>`- **${M$(J.display)}**:${M$(J.reason)}`).join(`
197
+ `)}]});return Z.push(...$.catalog.map(Oq),Rq($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function E5($){return{tag:"collapsible_panel",element_id:e8($.runId),header:{title:{tag:"plain_text",content:$6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${M$($.description??"说明 MISS")}**`,YH($).content,`**任务说明**
198
+ ${Eq($.prompt)}`,...$.workers.map((Z)=>JH(Z,QH($.workers.length)).content)].join(`
199
+
200
+ `)}]}}function e8($){return`ar_${Mq("sha256").update($).digest("hex").slice(0,16)}`}function x5($){if($.length===1)return $[0].summary;let Z=$.filter((Q)=>Q.terminal).length,J=$.filter((Q)=>Q.status==="failed").length,Y=$.filter((Q)=>Q.status==="needs_input"||Q.status==="paused").length;return`\uD83E\uDDE0 委派任务 · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Y?` · 待处理 ${Y}`:""}`}function JH($,Z=ZH){let J=Nq($),Y=[`模型 ${N1($.model)} · 推理 ${N1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${F0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",M$($.queuedReason));if($.pendingInput){Y.push("","**等待主 Agent 回答**");for(let Q of $.pendingInput.questions)if(Y.push(`- ${M$(Q.question)}`),Q.options.length)Y.push(` 选项:${Q.options.map((V)=>N1(V.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",Z0($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",xq(Z0($.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} ${N1(H)} ${M$(HH(Q.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${M$($.identityName)}**`,...Y].join(`
201
+ `)}}function YH($){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:[`**${VH($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${F0(z/1000)}`]:[],...$.error?[M$($.error)]:[]].join(`
202
+ `)}}function QH($){let Z=Math.max(1,Math.floor($));return Math.min(ZH,Math.max(Aq,Math.floor(Uq/Z)))}function $6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${VH($)} · ${HH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function Oq($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${M$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${N1($.id)}
203
+ ${N1($.model)} · 默认 ${N1($.defaultEffort??"MISS")} · ${M$(J)}`].join(`
204
+ `)}}function Rq($){return{tag:"column_set",columns:[N5("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),N5("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),N5("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function N5($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function Nq($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function Tq($){return $==="completed"||$==="failed"||$==="cancelled"}function VH($){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)=>Tq(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function Eq($){let Z=Z0($);if(Z.length<=$H)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,$H-J.length-2)}
205
+
206
+ ${J}`}function xq($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
207
+
208
+ ${J}`}function N1($){return"`"+$.replace(/`/g,"\\`")+"`"}function M$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function HH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var $H=1e4,Uq=48000,ZH=8000,Aq=512;var XH=O(()=>{S0()});function E1($){return Sq.has($)?$:null}function Z6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function S2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function T1($){return String($?.subject??$?.content??"").trim()}function S5($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function GH($){return`subj:${$}`}function zH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function yq($){let Z=T1($);if(!Z)return null;return{id:S2($)||GH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:S5($)??"pending"}}function C5($,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=yq(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=T1(_);if(!q)return;let P=G?.[j],D=P&&S2(P)||zH(Y??"");B=WH(B,D,q,_)}),B}let V=Z6(Y),H=V?.task??V,X=S2(H)||zH(Y??""),z=T1(H)||T1(J);if(!z)return $;return WH($,X,z,J)}if(Z==="TaskUpdate"){let Q=S2(J);if(!Q)return $;let V=S5(J);if(V==="deleted")return $.filter((X)=>X.id!==Q);let H=T1(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=S2(V)||S2(J);if(!H)return $;let X=$.find((G)=>G.id===H),z=T1(V)||X?.subject||T1(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:S5(V)??X?.status??"pending"};return X?$.map((G)=>G.id===H?W:G):[...$,W]}return $}function WH($,Z,J,Y){let Q=Z||GH(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 b5($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let H=bq[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 KH($,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=kq[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(`
209
+ `)}function Z1($,Z,J,Y){let Q=Cq[J.name],V=b5(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:KH(Z,Y)}]}}function x1($){return{tag:"collapsible_panel",element_id:R.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${b5($)}`}},expanded:!0,elements:[{tag:"markdown",content:KH($)}]}}var Sq,Cq,bq,kq;var BH=O(()=>{S0();Sq=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);Cq={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},bq={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},kq={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var t0=O(()=>{S0();R8();BV();hV();rV();eV();XH();BH();L3()});function _H($){if(!$||typeof $!=="object")return!1;let Z=$.response?.status??$.status,J=$.response?.data?.code??$.code;if(J===99991400||J===230020||J===1061045||vq.has(Z))return!0;if(typeof Z==="number"&&Z>=400)return!1;if(wq.has(J)||$.name==="TimeoutError")return!0;return $.cause!==$&&_H($.cause)}function fq($){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 S1($,Z){for(let J=0;;J++)try{return await Z()}catch(Y){let Q=Math.max(k5[J]??0,fq(Y)),V=_H(Y)&&J<k5.length&&Q<=60000;if(K(`feishu: ${$} attempt ${J+1}/${k5.length+1} failed: ${Y}; ${V?`retry in ${Q}ms`:"FINAL"}`),!V)throw Y;await new Promise((H)=>setTimeout(H,Q))}}async function C2($,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 U$(`${Z} HTTP ${$.status}: invalid JSON — ${J.slice(0,200)}`,$.status,void 0,Y)}if(!$.ok||Q?.code!==0)throw new U$(`${Z} HTTP ${$.status} code=${Q?.code??"MISS"} msg=${Q?.msg??"MISS"}`,$.status,Q?.code,Y);return Q}var k5,vq,wq,U$;var J6=O(()=>{f();k5=[1000,4000],vq=new Set([408,429,500,502,503,504]),wq=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"]);U$=class U$ extends Error{status;code;retryAfter;constructor($,Z,J,Y){super($);this.status=Z;this.code=J;this.retryAfter=Y;this.name="FeishuRequestError"}}});function Iq($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!hq.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 s4{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 jH($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class v5{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 y5($){if(Array.isArray($))return`[${$.map(y5).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)}:${y5(J)}`).join(",")}}`}function gq($){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${y5(V)}`}function mq($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${gq($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function pq(){return new Promise(($)=>setTimeout($,0))}function r4($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function LH($){let Z=$.afterAck??pq,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=Iq(Q);if(V)return $.responses.invalid(Q,V);let H=mq(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(_){r4($.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(_){r4($.deduper,H,!1),J(_);return}if(B){let _=B.then((j)=>{r4($.deduper,H,j==="complete")},(j)=>{r4($.deduper,H,!1),J(j)});$.track(_);return}r4($.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 hq;var w5=O(()=>{hq=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 cq}from"node:async_hooks";class qH{actor=new s4;context=new cq;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 X$($,Z){return uq.run($,Z)}var uq;var f5=O(()=>{w5();uq=new qH});async function h5($){let Z=await m5("feishu chat.get",()=>X0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)Y6("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 I5($,Z){let J=await m5("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)Y6("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 g5($){let Z=await m5("feishu tasklist.delete",()=>X0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)Y6("feishu tasklist.delete",Z)}function PH($,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 m5($,Z){try{return await Z()}catch(J){Y6($,J)}}function Y6($,Z){throw Error(PH($,Z))}var DH=O(()=>{t()});var J0={};N$(J0,{writeAliveMarker:()=>VZ,urgentApp:()=>k1,uploadImageKey:()=>_Z,uploadAndSend:()=>X9,updateCard:()=>w2,unbindSessionChat:()=>H6,tempProjectName:()=>O$,tempChatName:()=>$Z,setPendingConversationLaunchChecked:()=>Y1,sendTextRaw:()=>v,sendText:()=>E,sendImage:()=>L6,sendFile:()=>pH,sendCard:()=>c,sanitizeSessionName:()=>LZ,resolveProjectDir:()=>W6,replaceTurnAnchors:()=>e0,registerTempSessionLease:()=>n5,refreshChatList:()=>V9,readAliveMarker:()=>HZ,provisionProject:()=>jZ,projectProfile:()=>y2,preferredChatForSession:()=>L0,loadTempSessionLeases:()=>i5,loadSessionTurnsMap:()=>t5,loadSessionResumeMap:()=>r5,loadSessionModelMap:()=>ZZ,loadSessionChatMap:()=>o5,listNormalChatIdsByName:()=>K6,isOpenAIChatGPTAuthenticated:()=>z9,hasTempSessionLease:()=>a5,getTurnAnchors:()=>J9,getTenantToken:()=>A$,getSessionResumeRef:()=>J1,getSessionModelSelection:()=>YZ,getSessionBranchBase:()=>Y9,getPendingConversationLaunch:()=>Q9,getChatTailMessageId:()=>BZ,formatFeishuApiError:()=>PH,findNormalChatIdByName:()=>B6,fetchChatOwnerOpenId:()=>h5,fetchChatName:()=>KZ,ensureChatForSession:()=>XZ,downloadAttachment:()=>H9,disbandChatForSessionExact:()=>GZ,disbandChatForSession:()=>WZ,deleteTasklistByGuid:()=>g5,deleteReaction:()=>b0,createTempChatForSession:()=>zZ,createTasklistWithOwner:()=>I5,client:()=>X0,clearSessionResumeChecked:()=>v2,clearSessionConversationState:()=>QZ,chatNameCache:()=>q0,chatIdForSession:()=>G6,bindSessionToChat:()=>k2,bindSessionResumeChecked:()=>Z9,bindSessionModelChecked:()=>b1,bindSessionModel:()=>JZ,appendTurnAnchorChecked:()=>e5,addReaction:()=>u0,PROJECTS_ROOT:()=>bH,MAX_UPLOAD_BYTES:()=>j6});import*as NH from"@larksuiteoapi/node-sdk";import{execSync as lq}from"node:child_process";import{randomUUID as d5}from"node:crypto";import{mkdirSync as c5,readFileSync as C1,statSync as TH,writeFileSync as EH}from"node:fs";import{readFile as dq}from"node:fs/promises";import{homedir as FH}from"node:os";import{basename as b2,extname as iq,isAbsolute as xH,join as V6}from"node:path";import{sync as nq}from"cross-spawn";function u5(){let $={};for(let[Z,J]of c0)$[Z]=J;s(_7,$)}function i5(){c0.clear();try{let $=JSON.parse(C1(_7,"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"||!O$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){K(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}c0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}K(`feishu: loaded ${c0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")K(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function n5($,Z){if(!O$($))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 c0.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=c0.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};c0.set(Z,Y);try{u5()}catch(Q){if(J)c0.set(Z,J);else c0.delete(Z);throw Q}}function a5($,Z){let J=c0.get(Z);return J?.sessionName===$&&J.chatId===Z}function y2($){return h.projects[$]}function W6($){return y2($)?.cwd?.trim()||V6(bH,$)}function $9($,Z={}){return $0($,{...Z,signal:Z.signal??AbortSignal.timeout(kH)})}async function yH($,Z,J){let Y=Z.signal??AbortSignal.timeout(kH);try{return await C2(await $9($,{...Z,signal:Y}),J)}catch(Q){if(Y.aborted&&Y.reason?.name==="TimeoutError")throw Y.reason;throw Q}}async function A$(){if(Q6&&Date.now()<MH)return Q6;return p5??=(async()=>{let $=await yH("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:SH,app_secret:CH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return Q6=$.tenant_access_token,MH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,Q6})().finally(()=>{p5=null}),p5}function o5(){try{let $=JSON.parse(C1(W7,"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 vH(){try{l5()}catch($){K(`feishu: save session-chat-map failed: ${$}`)}}function l5(){let $={};for(let[Z,J]of L0)$[Z]=J;s(W7,$)}function k2($,Z){if(L0.get($)===Z)return;let J=L0.get($);L0.set($,Z),vH(),K(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function H6($){let Z=L0.get($);if(!Z)return;L0.delete($),vH(),K(`feishu: unbound session "${$}" from ${Z}`)}function t4($,Z){let J=j0.get($)??{};J[Z.provider]=Z,j0.set($,J)}function UH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=j$(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"||!xH(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function AH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!j$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!xH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function aq($,Z,J){if(typeof $!=="string")return AH($);if(!Z)throw Error("cannot bind a conversation without a provider");return AH({provider:Z,sessionId:$,cwd:J??null})}function r5(){try{let $=JSON.parse(C1(G7,"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()){t4(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=UH(Y);if(Q){t4(Z,Q);continue}for(let V of v7){let H=Y[V];if(typeof H==="string"&&H.trim()){t4(Z,{provider:V,sessionId:H.trim(),cwd:null});continue}let X=UH(H,V);if(X)t4(Z,X)}}K(`feishu: loaded ${j0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function X6(){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(G7,$)}function Z9($,Z,J,Y){let Q=aq(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;t4($,Q);try{X6()}catch(z){if(H)j0.set($,H);else j0.delete($);throw z}}function J1($,Z="codex"){let J=j0.get($)?.[Z];return J?{...J}:null}function v2($,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{X6()}catch(Q){throw j0.set($,Y),Q}}function wH($){if(!$||typeof $!=="object")return null;let Z=$;if(!j$(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 fH($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=wH(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 hH($){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=wH(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=fH(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 oq($){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 rq($,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=fH(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:oq(J.writes)}}function sq($){if(!$||typeof $!=="object")return null;let Z=$,J=hH(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 s5($){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 t5(){try{let $=JSON.parse(C1(K7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");e.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 _=hH(B.base);if(!_){J++;continue}H=_}if(Object.prototype.hasOwnProperty.call(B,"pendingLaunch")){let _=sq(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 _=rq(B,W);if(_)G.push(_);else J++}if(G.length||H!==null||X)e.set(Y,{base:H,anchors:G,...X?{pendingLaunch:X}:{}}),Z+=G.length}if(K(`feishu: loaded ${Z} turn anchors across ${e.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 e4(){let $={};for(let[Z,J]of e)$[Z]=J;s(K7,$)}function e5($,Z){let J=e.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>OH){let V=Y.splice(0,Y.length-OH),H=V[V.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}e.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{e4()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function J9($){return e.get($)?.anchors??[]}function Y9($){return e.get($)?.base??null}function Q9($){let Z=e.get($)?.pendingLaunch;return Z?s5(Z):null}function Y1($,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=e.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)e.delete($);else e.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:s5(Z)}:{}});try{e4()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function e0($,Z,J,Y){let Q=e.get($),V=Y===void 0?Q?.pendingLaunch:Y??void 0,H=V?s5(V):void 0;if(Z.length===0&&J===null&&!H)e.delete($);else e.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{e4()}catch(X){if(Q)e.set($,Q);else e.delete($);throw X}}function O$($){return RH.test($)?$.replace(RH,""):null}function $Z($,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(),...e.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;V.has(H);X++)H=`${$}*${Q}-${X}`;return H}function ZZ(){try{let $=JSON.parse(C1(B7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){C0.set(Z,{provider:V2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,V=j$(Q)?Q:typeof Y==="string"&&Y.trim()?V2(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"?K0(X)?X:null:V==="claude"?D0(X)?X:null:o0(X)?X:null;C0.set(Z,{provider:V,model:H,effort:G,...W?{tokenSourceId:W}:{}})}K(`feishu: loaded ${C0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")K(`feishu: load session-model-map failed: ${$?.message??$}`)}}function tq(){try{z6()}catch($){K(`feishu: save session-model-map failed: ${$}`)}}function z6(){let $={};for(let[Z,J]of C0)$[Z]=J;s(B7,$)}function JZ($,Z,J,Y,Q){let V=C0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;C0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),tq()}function b1($,Z,J,Y,Q){let V=C0.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;C0.set($,H);try{z6()}catch(X){if(V)C0.set($,V);else C0.delete($);throw X}}function YZ($){let Z=C0.get($);if(Z)return Z;let J=O$($);return J?C0.get(J)??null:null}function QZ($){let Z=L0.get($),J=j0.get($),Y=C0.get($),Q=e.get($),V=[...c0.entries()].filter(([,H])=>H.sessionName===$);L0.delete($),j0.delete($),C0.delete($),e.delete($);for(let[H]of V)c0.delete(H);try{l5(),X6(),z6(),e4(),u5()}catch(H){if(Z)L0.set($,Z);if(J)j0.set($,J);if(Y)C0.set($,Y);if(Q)e.set($,Q);for(let[z,W]of V)c0.set(z,W);let X=[H];for(let z of[l5,X6,z6,e4,u5])try{z()}catch(W){X.push(W)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function VZ($){s(L7,$)}function HZ(){let $;try{$=C1(L7,"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 G6($){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 V9(){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 K6(){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 B6($){let Z=L0.get($);if(Z&&q0.get(Z)===$){let V=await IH(Z);if(V.name===$&&gH(V.status))return Z;q0.delete(Z),H6($)}let Y=(await K6()).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 XZ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await B6($);if(J){let V=await eq(J,Z);return k2($,J),{chatId:J,created:!1,joined:V}}let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:d5()},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,$),k2($,Q),{chatId:Q,created:!0,joined:!0}}async function zZ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await B6($))throw Error(`temporary group name already exists: ${$}`);let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:d5()},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,$),k2($,Q),{chatId:Q,created:!0,joined:!0}}async function WZ($){let Z=await B6($);if(!Z)return H6($),{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)H6($);return{chatId:Z,disbanded:!0}}async function GZ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await IH(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!gH(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 eq($,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 KZ($){try{let Z=await A$(),Y=await(await $9(`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 _6($,Z,J,Y){let Q=d5();try{return await S1(`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 U$(`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 IH($){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 gH($){return $===null||$==="normal"}async function E($,Z){return X$($,()=>_6("Text",$,"text",JSON.stringify({text:Z})))}async function c($,Z){return X$($,()=>_6("Card",$,"interactive",JSON.stringify(a$(Z))))}async function BZ($){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 w2($,Z){let J=await X0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(a$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function v($,Z){return X$($,()=>$P($,Z))}async function $P($,Z){try{let J=await A$(),Q=await(await $9("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 u0($,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 b0($,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 k1($,Z){if(!$){K("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){K(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await A$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await $9(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 H9($,Z,J,Y){try{let Q=await A$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await $9(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());c5(q7,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,W=V6(q7,`${Date.now()}-${z}`);return EH(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 JP($){return ZP.has(iq($).toLowerCase())}async function mH($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Y;return S1(`${J} ${$}`,async()=>{if(Y??=new Blob([Uint8Array.from(await dq($))]),Y.size>j6)throw Error(`${b2($)} 超过 30 MB`);let Q=await A$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",b2($));V.append(Z,Y,b2($));let X=(await yH(`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 _Z($){try{let Z=TH($);if(!Z.isFile())return K(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>j6)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 mH($,"image")}catch{return null}}async function L6($,Z){return X$($,()=>_6("Image",$,"image",JSON.stringify({image_key:Z})))}async function pH($,Z){return X$($,()=>_6("File",$,"file",JSON.stringify({file_key:Z})))}async function X9($,Z){try{let Q=TH(Z);if(!Q.isFile())return K(`feishu: uploadAndSend not a file — ${Z}`),await E($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>j6)return K(`feishu: uploadAndSend oversize — ${Z} (${Q.size}B)`),await E($,`❌ 出站文件: ${b2(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return K(`feishu: uploadAndSend stat failed — ${Z}: ${Q}`),await E($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=JP(Z)?"image":"file",Y=J==="image"?"出站图片":"出站文件";try{let Q=await mH(Z,J),V=await(J==="image"?L6($,Q):pH($,Q));if(!V)return K(`feishu: uploadAndSend ${Z} send failed after upload`),await E($,`❌ ${Y}发送失败: ${b2(Z)}(上传已完成)`),!1;return K(`feishu: uploadAndSend ${Z} delivered msg=${V}`),!0}catch(Q){return K(`feishu: uploadAndSend ${Z} failed: ${Q}`),await E($,`❌ ${Y}上传失败: ${b2(Z)} — ${Q}`),!1}}function jZ($){c5($,{recursive:!0}),K(`feishu: provisioned ${$}`);let Z=V6(FH(),".codex","config.toml");try{c5(V6(FH(),".codex"),{recursive:!0});let J="";try{J=C1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
210
+
211
+ `:""}${Y}
212
+ trust_level = "trusted"
213
+ `,EH(Z,J)}}catch(J){K(`feishu: codex trust write failed for ${$}: ${J}`)}try{lq("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function z9($=u){let Z=nq(A4(),["login","status",...k.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:k.env($,{...process.env,...h.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}
214
+ ${Z.stderr}`)}function LZ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var SH,CH,bH,c0,X0,kH=15000,Q6="",MH=0,p5=null,q0,L0,j0,e,OH=200,RH,C0,j6=31457280,ZP;var t=O(()=>{f0();J6();f5();B0();k0();F1();B0();V0();f();m0();x0();S0();D1();DH();SH=h.feishu.app_id,CH=h.feishu.app_secret,bH=h.runtime.projects_root,c0=new Map;X0=new NH.Client({appId:SH,appSecret:CH,disableTokenCache:!1});q0=new Map,L0=new Map;j0=new Map;e=new Map;RH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;C0=new Map;ZP=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as cH,randomUUID as YP}from"node:crypto";function W9($,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 uH($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function W$($){let Z=z$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function $$($){return!z$.has($)}function Z$($,Z,J){z$.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 G9($){return z$.get($)?.elementCount??0}function lH($){let Z=z$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function f2($,Z){return z$.get($)?.deadElements.has(Z)??!1}function dH($,Z){let J=z$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function K9($){let Z=W$($);return Z.sequence+=1,Z.sequence}function qZ($,Z){$.deadElements.add(Z)}function iH($){return cH("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function zP($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==R.footer)Y.push(J);return cH("sha256").update(Y.sort().join(`
215
+ `)).digest("hex")}async function v1($,Z,J){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:YP()}:{}}):void 0,Q=`cardkit ${$} ${Z}`;return S1(Q,async()=>{let V=await A$(),H=AbortSignal.timeout(VP),X;try{return X=await $0(`${QP}${Z}`,{method:$,headers:{Authorization:`Bearer ${V}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:H}),(await C2(X,Q))?.data}catch(z){if(H.aborted&&H.reason?.name==="TimeoutError")throw H.reason;if(X&&z instanceof U$){let W=X.headers.get("x-tt-logid")??X.headers.get("x-request-id")??X.headers.get("request-id")??void 0;if(Object.assign(z,{httpStatus:X.status,logId:W}),W)z.message+=` log_id=${W}`}throw z}})}function WP($){return new Promise((Z)=>setTimeout(Z,$))}function GP($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function KP($){let Z=K9($);await v1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function q6($,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(W9(W.code,W))W.capacityFingerprint=zP(W$($),V.elementId,V.contentFingerprint);try{if(!Q)W$($).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(!GP(X)){K(`cardkit ${Z} ${$}: ${X}`),H(X);return}K(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await KP($)}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 BP($){return typeof $==="object"&&$!==null&&$.code===200740}async function G$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:HP,Y=null;for(let Q=0;Q<J.length;Q++){let V=J[Q]??0;if(V>0)await WP(V);try{let H=await v1("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,!BP(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 Q1($){let Z=z$.get($);if(!Z)return;await Z.queue}function U0($,Z,J={},Y){if($$($))return Promise.resolve();let Q=W$($);if(Q.closing)return Promise.resolve();let V=a$(Z),H=V.element_id,X=iH(V),z=()=>{if(!H)return;qZ(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>q6($,"addElement",async()=>{let W=K9($);if(await v1("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 Q0($,Z,J,Y,Q=!0){if($$($))return Promise.resolve();let V=W$($);if(V.closing)return Promise.resolve();let H=a$(J),X=iH(H),z=()=>{qZ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>q6($,`replaceElement ${Z}`,async()=>{let W=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!W&&!V.failedReplacements.has(Z))return;let G=K9($);if(W)await v1("POST",`/cards/${$}/elements`,{type:W.type??"append",...W.targetElementId?{target_element_id:W.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),V.elementCount++;else await v1("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 A0($,Z,J,Y={}){if($$($))return!1;let Q=W$($);if(Q.closing)return!1;let V=!1;return await Q0($,Z,J,()=>{V=!0},Y.notifyCardFailure!==!1),!V&&!Q.deadElements.has(Z)}async function nH($,Z,J){if($$($))return{landed:!1};let Y=W$($);if(Y.closing)return{landed:!1};let Q;return await Q0($,Z,J,(V,H)=>{Q=H}),{landed:!Q&&!Y.deadElements.has(Z),...Q?{failure:Q}:{}}}async function w1($,Z,J={}){return(await h2($,Z,J)).landed}async function h2($,Z,J={}){if($$($))return{landed:!1};let Y=W$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,V;return await U0($,Z,J,(H,X)=>{V=X}),{landed:!V&&!(Q&&Y.deadElements.has(Q)),...V?{failure:V}:{}}}function _P($,Z,J){if($$($))return Promise.resolve();let Y=W$($);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(()=>q6($,`deleteElement ${Z}`,async()=>{if(Q())return;let V=K9($);await v1("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),qZ(Y,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Y.queue}async function aH($,Z){if($$($))return!1;let J=W$($);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 _P($,Z,()=>{Y=!0}),!Y&&J.deadElements.has(Z)}function I2($,Z){if($$($)||z$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=y1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},y1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=y1.get($);if(!Q)return;if($$($)){y1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let V=Q.latest;R0($,{config:{summary:{content:V}}}).then((H)=>{let X=y1.get($);if(H&&X===Q)X.lastSent=V})},XP)}function y0($){let Z=y1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;y1.delete($)}function P6($,Z){return R0($,Z).then(()=>{})}async function R0($,Z){if($$($))return!1;let J=W$($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>q6($,"patchSettings",async()=>{if($$($))return;let V=K9($);await v1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:V}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!$$($)}async function J$($){let Z=z$.get($);if(!Z){y0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,y0($),await Z.queue,z$.delete($)}var QP="https://open.feishu.cn/open-apis/cardkit/v1",VP=15000,HP,z$,y1,XP=1500;var v$=O(()=>{f0();t();J6();f();S0();HP=[0,250,750,1500];z$=new Map,y1=new Map});class B9{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(oH($))}update($,Z=!1){return this.updateRow(oH($),Z)}syncBackground($,Z,J){return X$($,async()=>{let Y=this.background.get(Z);if(!Y)this.background.set(Z,Y=new Map);let Q=[];for(let V of J){let H=V.displayId??V.toolUseId??V.id,X=Y.get(H);if(X?.task===V&&!X.pendingSettings)continue;let z=X&&Q$(X.task)&&!Q$(V),W=(X?.version??0)+(z?1:0),G=`background:${Z}:${H}:${W}`,B={key:G,chatId:$,elementId:R4.panel(G),element:j3({...V,id:G}),summary:H8(V),status:V.status,terminal:Q$(V)};try{if(!X||z)await this.addRow(B);else await this.updateRow(B,B.terminal,!0);Y.set(H,{task:V,version:W})}catch(_){if(this.byTask.get(G)?.rows.get(G)===B)Y.set(H,{task:V,version:W,pendingSettings:!0});Q.push(_)}}if(Q.length)throw AggregateError(Q,Q.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return X$($.chatId,async()=>{if(this.byTask.get($.key)){await this.updateRow($,$.terminal,!0);return}let J=this.tails.get($.chatId);if(J){if(await this.deps.getChatTailMessageId($.chatId)===J.messageId&&this.deps.getElementCount(J.cardId)<jP){let Q=await this.deps.addElementResult(J.cardId,$.element);if(Q.landed){this.attach(J,$),await this.settings(J);return}if(!rH(Q))throw sH("agent card append",Q)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1){return X$($.chatId,async()=>{let Y=this.byTask.get($.key);if(!Y)return;if(Y.settled.has($.key)&&!J){if(Z)await this.settings(Y);return}let Q=[],V=await this.deps.replaceElementResult(Y.cardId,$.elementId,$.element);if(!V.landed){if(!rH(V)||Y.rows.size===1)throw sH("agent task row update",V);let H=Y;await this.seal(H,!0);let X=this.tails.get($.chatId);if(X)await this.seal(X);Y=await this.create($),H.rows.delete($.key),H.settled.delete($.key);try{if(!await this.deps.deleteElementChecked(H.cardId,$.elementId))throw Error("agent moved task row deletion MISS; the previous card may still show its earlier state")}catch(z){Q.push(String(z))}try{await this.settings(H)}catch(z){Q.push(String(z))}}if(Y.rows.set($.key,$),Z)Y.settled.add($.key);else Y.settled.delete($.key);try{await this.settings(Y)}catch(H){Q.push(String(H))}if(Q.length)throw Error(Q.join("; "))})}closeChat($){return X$($,async()=>{let Z=this.tails.get($);if(Z)await this.seal(Z)})}attach($,Z){if($.rows.set(Z.key,Z),this.byTask.set(Z.key,$),Z.terminal)$.settled.add(Z.key);Z.attach?.($.messageId)}async create($){let Z=await this.deps.sendCard($.chatId,{schema:"2.0",config:{update_multi:!0,streaming_mode:!$.terminal,summary:{content:$.summary}},body:{elements:[$.element]}});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,rows:new Map,settled:new Set,sealed:!1};return this.attach(Y,$),this.tails.set($.chatId,Y),Y}async seal($,Z=!1){if($.sealed=!0,this.tails.get($.chatId)===$)this.tails.delete($.chatId);await this.settings($,!Z)}async settings($,Z=!0){this.deps.cancelSummary($.cardId);let J=$.settled.size===$.rows.size,Y={config:{streaming_mode:!J,summary:{content:x5([...$.rows.values()])}}},Q=JSON.stringify(Y);if(Q!==$.settingsJson){if(!await this.deps.patchSettingsChecked($.cardId,Y))throw Error("agent card settings update MISS");$.settingsJson=Q}if(J&&$.sealed&&Z){await this.deps.dispose($.cardId);for(let V of $.rows.keys())if(this.byTask.get(V)===$)this.byTask.delete(V)}}}function oH($){return{key:`run:${$.runId}`,chatId:$.chatId,elementId:e8($.runId),element:E5($),summary:$6($),status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",attach:(Z)=>{$.cardMessageId=Z}}}function rH($){return W9($.failure?.code,$.failure)}function sH($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"})`:""}`)}var jP=50;var PZ=O(()=>{t0();v$();f5()});function tH(){return new B9(DZ)}var DZ;var FZ=O(()=>{PZ();v$();t();DZ={sendCard:c,getChatTailMessageId:BZ,convertMessageToCard:G$,recordCardCreated:Z$,getElementCount:G9,addElementResult:h2,replaceElementResult:nH,deleteElementChecked:aH,cancelSummary:y0,patchSettingsChecked:R0,dispose:J$}});var $X={};N$($X,{codexAccountSummary:()=>_9,codexAccountPanel:()=>j9,codexAccountCard:()=>K$,CODEX_ACCOUNTS_PAGE_SIZE:()=>D6});function V1($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function MZ($){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 _9($){let[Z,J]=eH[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function K$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:_9($)}},body:{elements:[j9($)]}}}function j9($){let[,,Z]=eH[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(v0(["连接","授权","就绪"].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(MZ([[l0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[v0(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),l0("登录账号,输入左侧验证码")]]))}if($.current)J.push(MZ([[l0("当前使用"),v0(`**${V1($.current)}**`)],...$.selected&&$.selected!==$.current?[[l0("下次启动"),v0(`**${V1($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(v0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>V1(Y)).join(" · ")));if($.message)J.push(v0(V1($.message)));if($.resetUsage){let Y=$.resetUsage;if(J.push(v0(`**重置卡** ${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(...T2(Q,V))}else J.push(v0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...LP($));if($.phase==="accounts")J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"⌨️ Codex 命令"},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",elements:[v0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
216
+ `)),l0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(l0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[v0(V1($.details))]});return{tag:"collapsible_panel",element_id:R.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:_9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function LP($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/D6)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[l0(`${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(l0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let H of Z.entries.slice((Y-1)*D6,Y*D6)){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(l0(`与「${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"?v0(`**#${j+1} · ${G.score.toPrecision(3)} 份/h**`):l0(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(l0(`周余量 ${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:[v0(V1(G.reason))]})}if(z.state!=="ok"){if(W.push(v0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[v0(V1(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(l0(`${B} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([j,q])=>j?[T2(j,q)]:[]);if(_.length)W.push(MZ(_))}if(J>1)Q.push(l0(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}var D6=4,eH,v0=($)=>({tag:"markdown",content:$}),l0=($)=>({tag:"markdown",content:`<font color='grey'>${V1($)}</font>`,text_size:"notation"});var g2=O(()=>{S0();eH={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"]}});import{readFileSync as qP}from"node:fs";import{homedir as PP}from"node:os";import{join as QX}from"node:path";function DP(){return process.env.CLAUDE_CONFIG_DIR||QX(PP(),".claude")}function AZ(){try{let $=qP(QX(DP(),"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 FP($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function MP($){let Z=FP($);return Z&&h1($)?Z:null}function JX($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function YX($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function UP($){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:JX(G.percentage),resetsAt:YX(G.nextResetTime)}:null,X=H(Y),z=H(Q),W=V?{percent:JX(V.percentage),resetsAt:YX(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 L9($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:AZ(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let V=MP(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(),ZX);try{let W=await $0(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 UP(B)}catch(W){let G=W?.name==="AbortError"?`timeout ${ZX}ms`:W?.message??String(W);return K(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(z)}}async function VX(){if(m2)return m2;return m2=L9().then(($)=>{if(m2=null,$.state==="network")return UZ??$;return UZ=$,$}).catch(($)=>{return K(`glm-usage: fetchGlmUsage threw: ${$}`),m2=null,UZ??{state:"network",reason:String($)}}),m2}var ZX=1e4,UZ=null,m2=null;var q9=O(()=>{f0();f()});import{homedir as AP}from"node:os";function M6($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function F6($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!M6($))throw Error(`Claude ${J}格式无效`);let Y=$.utilization;if(Y!==null&&(typeof Y!=="number"||!Number.isFinite(Y)||Y<0||Y>100))throw Error(`Claude ${J} utilization 缺失或无效`);let Q=$.resets_at;if(Q!==null&&(typeof Q!=="string"||!Number.isFinite(Date.parse(Q))))throw Error(`Claude ${J} resets_at 缺失或无效`);return{kind:Z,label:J,percent:Y,resetsAt:Q===null?null:new Date(Q)}}function XX($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function zX($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=XX(T4(Z.trim()));if(!J||J==="default")return null;let Y=$.windows.filter((Q)=>{let V=Q.kind.startsWith("modelWeekly:")?Q.kind.slice(12):Q.kind==="seven_day_opus"?"opus":Q.kind==="seven_day_sonnet"?"sonnet":null;return V!==null&&XX(V)===J});if(Y.length>1)return K(`Claude weekly usage MISS: ${Z} 匹配多个模型专属周额度窗口`),null;if(Y.length===1)return Y[0];return $.windows.find((Q)=>Q.kind==="weekly")??null}function OP($){if(!M6($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!M6($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[F6(Z.five_hour,"fiveHour","5h 窗口"),F6(Z.seven_day,"weekly","周额度")],Y=Z.five_hour!=null||Z.seven_day!=null;for(let[Q,V]of[["seven_day_oauth_apps","OAuth 应用周额度"],["seven_day_opus","Opus 周额度"],["seven_day_sonnet","Sonnet 周额度"]]){if(Z[Q]==null)continue;J.push(F6(Z[Q],Q,V)),Y=!0}if(Z.model_scoped!=null){if(!Array.isArray(Z.model_scoped))throw Error("Claude 模型专属额度 model_scoped 格式无效");for(let Q of Z.model_scoped){if(!M6(Q)||typeof Q.display_name!=="string"||!Q.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Q.display_name.trim();J.push(F6(Q,`modelWeekly:${V}`,`${V} 周额度`)),Y=!0}}if(!Y)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function WX($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (j2(),T3)),J=new Z({workDir:AP(),effort:"default",allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(V)=>K(`Claude subscription usage MISS: ${V.message}`));let Y,Q;try{let V=await Promise.race([J.readSubscriptionUsage(),new Promise((H,X)=>{Y=setTimeout(()=>X(Error(`Claude 订阅额度查询超时(${HX/1000}s)`)),HX)})]);return OP(V)}catch(V){throw Q=V instanceof Error?V:Error(String(V)),Q}finally{clearTimeout(Y);try{await J.kill()}catch(V){if(Q)throw AggregateError([Q,V],`${Q.message};额度查询进程关闭失败:${V instanceof Error?V.message:String(V)}`);throw V}}}catch(Z){let J=Z instanceof Error?Z.message:String(Z);return K(`claude-sub readUsage MISS: ${J}`),{state:Z?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING"?"no_credentials":"network",windows:[],reason:J}}}var HX=30000;var OZ=O(()=>{f();D3()});function GX($){let Z=[];for(let J of $.matchAll(RP)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function U6($,Z=process.platform){if(Z!=="win32")return $;let J=NP.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var RP,NP;var RZ=O(()=>{RP=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;NP=/^\/([a-zA-Z])\//});function _X($){if(KX.test($))return{marker:"start",body:$.replace(KX,"")};if(BX.test($))return{marker:"end",body:$.replace(BX,"")};return{marker:"none",body:$}}var KX,BX;var jX=O(()=>{KX=/^>{3,}[ \t]?/,BX=/^<{3,}[ \t]?/});async function LX($,Z,J,Y,Q){let{marker:V,body:H}=_X(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)TZ($,"reopen");return $.multiMsgBuffer=[],NZ($,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}NZ($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await EP($,X,z),!0}if($.multiMsgBuffer!==null)return NZ($,Z,J,Y,Q),!0;return!1}function NZ($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)TP($,Q)}function TP($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await u0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else b0(Z,J)})()}async function EP($,Z,J){for(let[H,X]of J)if(X)b0(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(" ")+`
216
217
  `:"")+H.text}).join(`
217
218
 
218
- `),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 MZ($,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)k0(Y,Q);l0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var VX=O(()=>{t();f();YX()});import{mkdtemp as UP,rm as MP,writeFile as AP}from"node:fs/promises";import{createRequire as OP}from"node:module";import{tmpdir as RP}from"node:os";import{join as HX}from"node:path";function kP($){let Z=GX.get($);if(Z)return Z;let{liteAdaptor:J}=u1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=u1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=u1("mathjax-full/js/mathjax.js"),{TeX:V}=u1("mathjax-full/js/input/tex.js"),{AllPackages:H}=u1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=u1("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 GX.set($,G),G}function KX($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function yP($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function wP($,Z=RZ,J=!0){try{let Y=Z*NP,{adaptor:Q,doc:V}=kP(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 _=KX(B.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=KX(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,U,A]=P,M=/<text\b/.test(G)?bP:0,S=`${D} ${T} ${U+M} ${A}`,b=_*Y,v=M*(b/U),y=Math.max(1,Math.ceil(b+v)),g=Math.max(1,Math.ceil(j*Y)),x=TP-AZ*2,I=Math.min(1,x/y),p=Math.max(1,Math.round(y*I)),l=Math.max(1,Math.round(g*I));if(I<1&&l<EP)throw Error(`formula would be unreadable after width cap (${p}x${l})`);let F=p+AZ*2,C=l+zX*2,d=G.slice(B.length,-6).replace(/currentColor/g,XX).replace(/font-family="serif"/g,`font-family="${CP}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${F}" height="${C}" viewBox="0 0 ${F} ${C}" style="color:${XX}">`,`<rect x="0" y="0" width="${F}" height="${C}" rx="6" fill="${LX}"/>`,`<svg x="${AZ}" y="${zX}" width="${p}" height="${l}" viewBox="${yP(S)}" preserveAspectRatio="xMidYMid meet">`,d,"</svg>","</svg>"].join(""),width:F,height:C}}catch(Y){return K(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function vP($,Z=RZ,J=!0){let Y=wP($,Z,J);if(!Y)return null;try{let{Resvg:Q}=u1("@resvg/resvg-js"),H=new Q(Y.svg,{background:LX,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:WX,sansSerifFamily:WX}}).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 fP($){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 BX($,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(fP(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 qX($){let Z=e7($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...BX($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...BX($.slice(Y),Y));return J}function hP($){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(_X[Y])return _X[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 pP($){let Z=jX.get($);if(Z!==void 0)return Z;return Z=gP++,jX.set($,Z),Z}function cP($,Z){return`${SP}\x00${pP(Z)}\x00${$}`}function uP($){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 lP($,Z){let J=cP($,Z),Y=c1.get(J);if(Y)return Y;let Q=OZ.get(J);if(Q)return Q;let V=(async()=>{let H=vP($,RZ,!0);if(!H)return null;let X=null;try{X=await UP(HX(RP(),"lodestar-math-"));let z=HX(X,`formula-${uP($)}.png`);await AP(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(c1.has(J))c1.delete(J);c1.set(J,G);while(c1.size>mP){let B=c1.keys().next().value;if(typeof B!=="string")break;c1.delete(B)}return G}catch(z){return K(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(X)try{await MP(X,{recursive:!0,force:!0})}catch(z){K(`math-render: temp cleanup failed for ${X}: ${z}`)}}})();OZ.set(J,V);try{return await V}finally{OZ.delete(J)}}function dP($,Z,J){let Y=$.width<=xP;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 PX($,Z={}){let J=qX($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??IP,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let B=hP(G.tex);if(B!==null)return{unicode:B,uploaded:null}}return{unicode:null,uploaded:await lP(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(dP(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 NZ($){return qX($).length>0}var u1,NP=0.5,RZ=22,XX="#1F2329",LX="#F7F8FA",AZ=12,zX=8,TP=720,EP=14,xP=278,SP="v4-native-cjk-tail-pad",bP=1100,WX,CP="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",GX,_X,IP=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (t(),Q0));return Z($)},jX,gP=1,c1,OZ,mP=512;var DX=O(()=>{f();u1=OP(import.meta.url),WX=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",GX=new Map;_X={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:"Ω"};jX=new WeakMap,c1=new Map,OZ=new Map});import{readFileSync as nP}from"node:fs";function c2($){return TZ.has($)}function D9($){TZ.add($)}function F9($){TZ.delete($)}function u2(){try{let $={};for(let[Z,J]of n0)$[Z]=J;s(M6,$)}catch($){throw K(`notify-callbacks: save failed (${M6}): ${$}`),$}}function AX(){let $=[],Z;try{Z=nP(M6,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-MX,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(n0.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(K(`notify-callbacks: loaded ${n0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),V)K(`notify-callbacks: ${V} interrupted text reply(s) marked UNKNOWN`);if(Q>0||V>0)u2()}catch(J){K(`notify-callbacks: load failed (${M6}): ${J}`)}return $}function OX($){let Z=Date.now();if(Z-UX>=aP)oP(Z),UX=Z;n0.set($.notifyId,$),u2()}function I$($){return n0.get($)}function EZ($){return[...n0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function U9($,Z){if(!$)return;return EZ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function RX($,Z){return!!Z&&[...n0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function l2($,Z){let J=n0.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{u2()}catch(V){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw V}}function M9($,Z,J){let Y=n0.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{u2()}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 xZ($,Z,J,Y){let Q=n0.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,u2()}function A6($,Z,J){try{return M9($,Z,J),{state:"complete"}}catch(Y){let V=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{xZ($,Z,J,V)}catch(H){let X=H instanceof Error?H.message:String(H);V+=`; unknown tombstone persistence also failed: ${X}`;let z=n0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function oP($=Date.now()){let Z=$-MX,J=0;for(let[Y,Q]of n0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)n0.delete(Y),J++;if(J>0)u2();return J}async function SZ($,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(),FX);try{let H=await zY($.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:`回调超时 ${FX}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(V)}}function NX($){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 MX=604800000,FX=2500,n0,UX,aP=86400000,TZ,M6;var A9=O(()=>{h0();f();V0();S0();n0=new Map,UX=Date.now(),TZ=new Set;M6=oJ});function O6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function d2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(U9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(O6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function bZ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:U9($.chatId)?"notification":O6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function CZ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||d2($,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(N0(Y.cardId),await c8(Y.cardId,{config:{summary:{content:X}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||d2($,Z))return;await C1(Y.messageId,[Y.userOpenId])})().catch((z)=>K(`session "${$.sessionName}": question notification failed: ${z}`))}function R6($){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=bZ($,J);if(V.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;J0(Z.cardId,N.tool(Q.i),f2(Q.i,J,Y.questions,"\uD83E\uDD14",V)),CZ($,J)}}function TX($){return O6($)!==void 0}async function EX($,Z,J,Y){let Q=O6($);if(!Q){K(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[V,H]=Q,X=d2($,V);if(X){let W=`${X}。这条文字未提交,请稍后重新发送。`;if(!await E($.chatId,W))throw Error(`提问等待提示发送失败: ${W}`);return}if(await kZ($,V,H.currentIdx,Z,J)&&Y)l0(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 SX($,Z,{optionIdx:Y,user:Q})}async function kZ($,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 SX($,Z,{customText:H,user:Q})}function SX($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=d2($,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 _=f2(B.i,Z,Y.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Y.answered});J0(G.cardId,N.tool(B.i),_)}if(W===void 0)if(Y.requestId)yZ($,Z);else K(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),R6($);return!0}function yZ($,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),R6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var N6=O(()=>{v$();Q$();t();f();A9()});import{isAbsolute as sP}from"node:path";function T0($){if($?.planLiveInserted)return N.planLive;return $?.taskLiveInserted?N.taskBoardLive:N.footer}function tP($){return $==="ImageGeneration"||$==="imageGeneration"}function eP($,Z,J){if(J||!tP($))return null;let Y=U6(Z.trim());return sP(Y)?Y:null}function $D($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function bX($,Z,J){return $==="read"?z9(Z,J):X9(Z,J)}function CX($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=$D(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"?z9(z,W.items):X9(z,W.items);J0($.currentTurn.cardId,N.tool(z),B),T6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let V=g1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,A0(z.cardId,m1($.taskBoard),{type:"insert_before",targetElementId:N.footer});else J0(z.cardId,N.taskBoardLive,m1($.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 _=W1(B,$.taskBoard,{name:V,status:"⏳"});G?A0(z.cardId,_,{type:"insert_before",targetElementId:T0(z)}):J0(z.cardId,N.tool(B),_),T6(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"?z9(H,z):X9(H,z);A0($.currentTurn.cardId,W,{type:"insert_before",targetElementId:T0($.currentTurn)}),T6($.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=f2(H,Z,z,"\uD83E\uDD14",bZ($,Z));A0($.currentTurn.cardId,B,{type:"insert_before",targetElementId:T0($.currentTurn)}),CZ($,Z);return}let X=R$(H,J,Y,null,"⏳");A0($.currentTurn.cardId,X,{type:"insert_before",targetElementId:T0($.currentTurn)}),T6($.currentTurn,J,Y)}function T6($,Z,J){if(!$)return;let Y=Q1(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,V=f1(Z),H=Q?`\uD83D\uDD27 ${V}: ${Q}`:`\uD83D\uDD27 ${V}`;w1($.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(`
219
- `):JSON.stringify(J);if(V.output=H,V.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let X=eP(V.name,H,Y);if(X){ZD($,$.currentTurn,V,X),O9($);return}if(V.name==="AskUserQuestion"){O9($);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 _=bX(G.kind,V.i,G.items);J0($.currentTurn.cardId,N.tool(V.i),_)}O9($);return}let z=g1(V.name);if(z){JD($,V,z,V.input,H,Y,V.resolvedNote);return}let W=R$(V.i,V.name,V.input,H,Y?"❌":"✅",V.resolvedNote);J0($.currentTurn.cardId,N.tool(V.i),W),O9($)}function ZD($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,V=N.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 P5(Y)}catch(B){K(`generated image upload failed: ${B}`)}if(W){let B=!1;try{B=await O0(Q,V,R$(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 m8($.chatId,W)!==null:await r4($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else K(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await O0(Q,V,R$(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 wZ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function JD($,Z,J,Y,Q,V,H){if(!$.currentTurn)return;if(!V)$.taskBoard=LZ($.taskBoard,J,Y,Q);let X=W1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},H);if(J0($.currentTurn.cardId,N.tool(Z.i),X),$.currentTurn.taskLiveInserted)J0($.currentTurn.cardId,N.taskBoardLive,m1($.taskBoard));O9($)}function O9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function vZ($,Z,J,Y,Q,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=y2(Z,N.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}),A0(J,bX(U,A,[M]),{type:"insert_before",targetElementId:T0(H)});continue}let P=g1(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?"⏳":_?"❌":"✅",b=W1(M,$.taskBoard,{name:P,status:S},z.resolvedNote);A?A0(J,b,{type:"insert_before",targetElementId:T0(H)}):J0(J,N.tool(M),b);continue}let D=H.toolCount++;H.toolByUseId.set(X,{...z,i:D});let T=!j?"⏳":_?"❌":"✅";A0(J,R$(D,z.name,z.input,B,T,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:T0(H)})}}var yX=O(()=>{FZ();v$();Q$();t();f();N6()});async function wX($,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=g1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,B=W?W1(z.i,$.taskBoard,{name:W,status:"❌"},G):R$(z.i,z.name,z.input,G,"❌");J0(X.cardId,N.tool(z.i),B)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let B=W?W1(z.i,$.taskBoard,{name:W,status:"⏳"},z.resolvedNote):R$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);J0(X.cardId,N.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 vX($,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)yZ($,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=u5(Q.i,Q.name,Q.input,Z.request_id);if(J0(J.cardId,N.tool(Q.i),V),J.userOpenId&&J.messageId){let H=Q1(Q.name,Q.input),X=f1(Q.name),z=H&&H.length>30?H.slice(0,30)+"…":H,W=z?`\uD83D\uDD10 等审批: ${X} · ${z}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{N0(J.cardId),await c8(J.cardId,{config:{summary:{content:W}}}),await C1(J.messageId,[J.userOpenId])})()}}var fX=O(()=>{v$();Q$();t();f();N6()});class hX{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new T1({accountId:Q,login:!0}),Z=900000,J=(Q,V)=>{k.recordLogin(Q,V),R2(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=YQ($),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,E6(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};取消请求失败:${E6(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=E6(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,`登录进程关闭失败:${E6(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 E6($){return $ instanceof Error?$:Error(String($))}var l1;var fZ=O(()=>{w$();p0();f();l1=new hX});function IX($){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 gX=O(()=>{p0();w$()});class i2{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=VD){let Y=await J.sendCard($,H$(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new i2(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=I4($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=I4($);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,N.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:h4($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var VD;var mX=O(()=>{t();v$();b0();E2();VD={sendCard:c,convertMessageToCard:J$,recordCardCreated:d0,replaceElementChecked:O0,patchSettingsChecked:D0,dispose:v0}});var IZ={};E$(IZ,{settleCodexAccountCards:()=>hZ,runCodexNamedHi:()=>XD,runCodexAccountCommand:()=>zD});import{createHash as HD}from"node:crypto";function R9($,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 pX($,Z){if(!await c($.chatId,H$(R9(Z))))throw Error("Codex 错误卡片发送失败")}async function XD($,Z){let J=await i2.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(R9(Y,Z))}}async function hZ(){let Z=(await Promise.allSettled([...d1.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function zD($,Z,J,Y,Q){if(Z==="reset"){await GD($,J,Q);return}let V={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let z=l1.pending(V);if(!J&&z.length!==1)throw Error(z.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?k.find(J).id:z[0];await l1.cancel(W,V),await d1.get(W)}catch(z){await pX($,z)}return}let H=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,X=await i2.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(d1.has(_.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:j}=k.remove(_.id);R2(_.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 R8.choose({model:j,effort:q}),D=IX(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")b1($.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(J8(z.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(d1.has(z.id))throw Error("登录结果正在更新,请稍等");let W=await l1.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 l1.cancel(z.id,V),_}let G=(async()=>{let _;try{_=await W.done}catch(q){await X.finish(R9(q,z.name));return}await X.update({phase:"checking",flow:"login",name:z.name,message:"授权完成,正在读取模型…"});let j;try{await O2();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}`})})();d1.set(z.id,G);let B=()=>{if(d1.get(z.id)===G)d1.delete(z.id)};G.then(B,(_)=>{K(`codex-login: terminal card write failed: ${_}`),B()})}catch(z){K(`codex-${Z}: ${z}`),await X.finish(R9(z,H))}}async function GD($,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(r0($.proc))}catch(W){K(`codex-reset: ${W}`),await pX($,W);return}let Q=await i2.open($.chatId,{phase:"checking",name:Y.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let W=HD("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await nQ(Y.id,W)}catch(W){K(`codex-reset: ${W}`),await Q.finish(R9(W,Y.name));return}let H=WD[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(`
220
- `);await Q.finish({...H,name:Y.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var d1,WD;var x6=O(()=>{t();p0();fZ();Y0();gX();C3();mX();E2();f();w$();d1=new Map;WD={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});function F0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function gZ($,Z){let J=$.agent==="claude"?k7.filter((Q)=>Q!=="default"):$.agent==="codex"?[...t7]:["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 S6($,Z){let J=$.modelSelection,Y=new Set(F0(Z.hidden_models)),Q=[...new Set([...F0(Z.custom_models),...J?[]:F0(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",...gZ($,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 i1=O(()=>{_0();O1()});import{homedir as KD}from"node:os";function lX($,Z=uX){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 cX($){return typeof $==="string"&&BD.includes($)?$:null}async function b6($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (S4(),pQ)),J=new Z({workDir:KD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Y)=>K(`Claude model catalog MISS: ${Y.message}`));try{let Y=await lX(J.listModels());if(!Y.length)throw Error("Claude SDK model catalog is empty");return Y.map((Q)=>({model:Q.model.replace(/^claude:/,""),display:Q.displayName,efforts:Q.supportedReasoningEfforts.map((V)=>V.reasoningEffort),defaultEffort:Q.defaultReasoningEffort}))}finally{await J.kill()}}async function dX($="default"){let Z=new T1({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 lX(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)=>cX(W?.reasoningEffort)).filter((W)=>W!==null);if(!X.length)continue;let z=cX(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 iX($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,V=await $0(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(uX)});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:n2,defaultEffort:"max"}})}var uX=1e4,BD,n2;var a2=O(()=>{h0();w$();f();BD=["none","minimal","low","medium","high","xhigh","max","ultra"];n2=["max","xhigh","high","medium","low"]});import{existsSync as _D}from"node:fs";import{join as jD}from"node:path";function nX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function LD($){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(nX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(nX($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function aX($){return $===u||_D(jD(k.home($),"auth.json"))}var oX=O(()=>{y0();Y0();w$();a2();f();p0();i1();M0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let H=aX(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=aX(V),!W.enabled){W.models=[],W.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}W.modelCatalogState={status:"loading",updatedAt:null};try{if(W.models=await dX(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=e0(G);return Object.assign(B,h.codex.env),k.env(V,B)},resolveSpawnModel(G){return G},async readUsage(){return LD(await E1(V))}};return W},Y=J(u);Y.forAccount=(V)=>{if(V===u)return Y;let H=k.revision(V),X=Z.get(V);if(X?.revision===H)return X.source;let z=S6(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!==u).map((V)=>Y.forAccount(V.id).refreshModels())])},Y}})});function PD($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function C6($,Z,J){try{let Y=await $0(PD($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(qD)});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 qD=15000;var mZ=O(()=>{h0();f()});function rX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function DD($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function sX($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function FD($){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 UD($){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 pZ($){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(rX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(rX($.weekly,"weekly","周额度"));if($.monthly)Z.push(DD($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var cZ=O(()=>{Y0();P9();a2();x4();mZ();f();M0({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)&&p1(J),V=$.model?.trim()||void 0,H=UD($.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 iX(J,Y),G=[...new Set([...sX($.models),...sX($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:n2,defaultEffort:"max",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=FD(X.models.map((B)=>B.model));for(let B of X.models){let _=q2("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={...e0(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 G8("glm",z)},async verifyModel(z){return C6(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return pZ(await q9(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
219
+ `),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 TZ($,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)b0(Y,Q);u0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var qX=O(()=>{t();f();jX()});import{mkdtemp as SP,rm as CP,writeFile as bP}from"node:fs/promises";import{createRequire as kP}from"node:module";import{tmpdir as yP}from"node:os";import{join as PX}from"node:path";function pP($){let Z=UX.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 UX.set($,G),G}function AX($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function cP($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function uP($,Z=SZ,J=!0){try{let Y=Z*vP,{adaptor:Q,doc:V}=pP(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 G0=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(G0)}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 _=AX(B.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=AX(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((G0)=>!Number.isFinite(G0))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,T,M,A]=P,U=/<text\b/.test(G)?gP:0,S=`${D} ${T} ${M+U} ${A}`,C=_*Y,w=U*(C/M),y=Math.max(1,Math.ceil(C+w)),g=Math.max(1,Math.ceil(j*Y)),x=wP-EZ*2,I=Math.min(1,x/y),p=Math.max(1,Math.round(y*I)),l=Math.max(1,Math.round(g*I));if(I<1&&l<fP)throw Error(`formula would be unreadable after width cap (${p}x${l})`);let F=p+EZ*2,b=l+FX*2,d=G.slice(B.length,-6).replace(/currentColor/g,DX).replace(/font-family="serif"/g,`font-family="${mP}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${F}" height="${b}" viewBox="0 0 ${F} ${b}" style="color:${DX}">`,`<rect x="0" y="0" width="${F}" height="${b}" rx="6" fill="${TX}"/>`,`<svg x="${EZ}" y="${FX}" width="${p}" height="${l}" viewBox="${cP(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 lP($,Z=SZ,J=!0){let Y=uP($,Z,J);if(!Y)return null;try{let{Resvg:Q}=g1("@resvg/resvg-js"),H=new Q(Y.svg,{background:TX,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:MX,sansSerifFamily:MX}}).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 dP($){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 OX($,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(dP(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 EX($){let Z=J3($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...OX($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...OX($.slice(Y),Y));return J}function iP($){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(RX[Y])return RX[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 rP($){let Z=NX.get($);if(Z!==void 0)return Z;return Z=aP++,NX.set($,Z),Z}function sP($,Z){return`${IP}\x00${rP(Z)}\x00${$}`}function tP($){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 eP($,Z){let J=sP($,Z),Y=I1.get(J);if(Y)return Y;let Q=xZ.get(J);if(Q)return Q;let V=(async()=>{let H=lP($,SZ,!0);if(!H)return null;let X=null;try{X=await SP(PX(yP(),"lodestar-math-"));let z=PX(X,`formula-${tP($)}.png`);await bP(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>oP){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 CP(X,{recursive:!0,force:!0})}catch(z){K(`math-render: temp cleanup failed for ${X}: ${z}`)}}})();xZ.set(J,V);try{return await V}finally{xZ.delete(J)}}function $D($,Z,J){let Y=$.width<=hP;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 xX($,Z={}){let J=EX($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??nP,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let B=iP(G.tex);if(B!==null)return{unicode:B,uploaded:null}}return{unicode:null,uploaded:await eP(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($D(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 CZ($){return EX($).length>0}var g1,vP=0.5,SZ=22,DX="#1F2329",TX="#F7F8FA",EZ=12,FX=8,wP=720,fP=14,hP=278,IP="v4-native-cjk-tail-pad",gP=1100,MX,mP="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",UX,RX,nP=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (t(),J0));return Z($)},NX,aP=1,I1,xZ,oP=512;var SX=O(()=>{f();g1=kP(import.meta.url),MX=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",UX=new Map;RX={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:"Ω"};NX=new WeakMap,I1=new Map,xZ=new Map});import{readFileSync as JD}from"node:fs";function p2($){return bZ.has($)}function P9($){bZ.add($)}function D9($){bZ.delete($)}function c2(){try{let $={};for(let[Z,J]of d0)$[Z]=J;s(A6,$)}catch($){throw K(`notify-callbacks: save failed (${A6}): ${$}`),$}}function yX(){let $=[],Z;try{Z=JD(A6,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-kX,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)c2()}catch(J){K(`notify-callbacks: load failed (${A6}): ${J}`)}return $}function vX($){let Z=Date.now();if(Z-bX>=YD)QD(Z),bX=Z;d0.set($.notifyId,$),c2()}function w$($){return d0.get($)}function kZ($){return[...d0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function F9($,Z){if(!$)return;return kZ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function wX($,Z){return!!Z&&[...d0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function u2($,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{c2()}catch(V){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw V}}function M9($,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{c2()}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 yZ($,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,c2()}function O6($,Z,J){try{return M9($,Z,J),{state:"complete"}}catch(Y){let V=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{yZ($,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 QD($=Date.now()){let Z=$-kX,J=0;for(let[Y,Q]of d0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)d0.delete(Y),J++;if(J>0)c2();return J}async function vZ($,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(),CX);try{let H=await BY($.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:`回调超时 ${CX}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(V)}}function fX($){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 kX=604800000,CX=2500,d0,bX,YD=86400000,bZ,A6;var U9=O(()=>{f0();f();V0();x0();d0=new Map,bX=Date.now(),bZ=new Set;A6=eJ});function R6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function l2($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(F9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(R6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function wZ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:F9($.chatId)?"notification":R6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function fZ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||l2($,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(y0(Y.cardId),await P6(Y.cardId,{config:{summary:{content:X}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||l2($,Z))return;await k1(Y.messageId,[Y.userOpenId])})().catch((z)=>K(`session "${$.sessionName}": question notification failed: ${z}`))}function N6($){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=wZ($,J);if(V.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;Q0(Z.cardId,R.tool(Q.i),O2(Q.i,J,Y.questions,"\uD83E\uDD14",V)),fZ($,J)}}function hX($){return R6($)!==void 0}async function IX($,Z,J,Y){let Q=R6($);if(!Q){K(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[V,H]=Q,X=l2($,V);if(X){let W=`${X}。这条文字未提交,请稍后重新发送。`;if(!await E($.chatId,W))throw Error(`提问等待提示发送失败: ${W}`);return}if(await hZ($,V,H.currentIdx,Z,J)&&Y)u0(Y,"CheckMark")}async function gX($,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 mX($,Z,{optionIdx:Y,user:Q})}async function hZ($,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 mX($,Z,{customText:H,user:Q})}function mX($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=l2($,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 _=O2(B.i,Z,Y.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Y.answered});Q0(G.cardId,R.tool(B.i),_)}if(W===void 0)if(Y.requestId)IZ($,Z);else K(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),N6($);return!0}function IZ($,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),N6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var T6=O(()=>{v$();t0();t();f();U9()});import{isAbsolute as HD}from"node:path";function N0($){if($?.planLiveInserted)return R.planLive;return $?.taskLiveInserted?R.taskBoardLive:R.footer}function XD($){return $==="ImageGeneration"||$==="imageGeneration"}function zD($,Z,J){if(J||!XD($))return null;let Y=U6(Z.trim());return HD(Y)?Y:null}function WD($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function pX($,Z,J){return $==="read"?l4(Z,J):u4(Z,J)}function cX($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=WD(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"?l4(z,W.items):u4(z,W.items);Q0($.currentTurn.cardId,R.tool(z),B),E6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let V=E1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,U0(z.cardId,x1($.taskBoard),{type:"insert_before",targetElementId:R.footer});else Q0(z.cardId,R.taskBoardLive,x1($.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 _=Z1(B,$.taskBoard,{name:V,status:"⏳"});G?U0(z.cardId,_,{type:"insert_before",targetElementId:N0(z)}):Q0(z.cardId,R.tool(B),_),E6(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"?l4(H,z):u4(H,z);U0($.currentTurn.cardId,W,{type:"insert_before",targetElementId:N0($.currentTurn)}),E6($.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=O2(H,Z,z,"\uD83E\uDD14",wZ($,Z));U0($.currentTurn.cardId,B,{type:"insert_before",targetElementId:N0($.currentTurn)}),fZ($,Z);return}let X=F$(H,J,Y,null,"⏳");U0($.currentTurn.cardId,X,{type:"insert_before",targetElementId:N0($.currentTurn)}),E6($.currentTurn,J,Y)}function E6($,Z,J){if(!$)return;let Y=r$(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,V=O1(Z),H=Q?`\uD83D\uDD27 ${V}: ${Q}`:`\uD83D\uDD27 ${V}`;I2($.cardId,H)}function uX($,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(`
220
+ `):JSON.stringify(J);if(V.output=H,V.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let X=zD(V.name,H,Y);if(X){GD($,$.currentTurn,V,X),m1($);return}if(V.name==="AskUserQuestion"){m1($);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 _=pX(G.kind,V.i,G.items);Q0($.currentTurn.cardId,R.tool(V.i),_)}m1($);return}let z=E1(V.name);if(z){KD($,V,z,V.input,H,Y,V.resolvedNote);return}let W=F$(V.i,V.name,V.input,H,Y?"❌":"✅",V.resolvedNote);Q0($.currentTurn.cardId,R.tool(V.i),W),m1($)}function GD($,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 _Z(Y)}catch(B){K(`generated image upload failed: ${B}`)}if(W){let B=!1;try{B=await A0(Q,V,F$(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 L6($.chatId,W)!==null:await X9($.chatId,Y);if(G)Z.outboundSentPaths.add(Y);else K(`generated image delivery failed: ${Y}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await A0(Q,V,F$(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 gZ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function KD($,Z,J,Y,Q,V,H){if(!$.currentTurn)return;if(!V)$.taskBoard=C5($.taskBoard,J,Y,Q);let X=Z1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},H);if(Q0($.currentTurn.cardId,R.tool(Z.i),X),$.currentTurn.taskLiveInserted)Q0($.currentTurn.cardId,R.taskBoardLive,x1($.taskBoard));m1($)}function m1($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())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 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=f2(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}),U0(J,pX(M,A,[U]),{type:"insert_before",targetElementId:N0(H)});continue}let P=E1(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=Z1(U,$.taskBoard,{name:P,status:S},z.resolvedNote);A?U0(J,C,{type:"insert_before",targetElementId:N0(H)}):Q0(J,R.tool(U),C);continue}let D=H.toolCount++;H.toolByUseId.set(X,{...z,i:D});let T=!j?"⏳":_?"❌":"✅";U0(J,F$(D,z.name,z.input,B,T,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:N0(H)})}}var lX=O(()=>{RZ();v$();t0();t();f();T6()});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=E1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,B=W?Z1(z.i,$.taskBoard,{name:W,status:"❌"},G):F$(z.i,z.name,z.input,G,"❌");Q0(X.cardId,R.tool(z.i),B)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let B=W?Z1(z.i,$.taskBoard,{name:W,status:"⏳"},z.resolvedNote):F$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);Q0(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 iX($,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)IZ($,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=V5(Q.i,Q.name,Q.input,Z.request_id);if(Q0(J.cardId,R.tool(Q.i),V),J.userOpenId&&J.messageId){let H=r$(Q.name,Q.input),X=O1(Q.name),z=H&&H.length>30?H.slice(0,30)+"…":H,W=z?`\uD83D\uDD10 等审批: ${X} · ${z}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{y0(J.cardId),await P6(J.cardId,{config:{summary:{content:W}}}),await k1(J.messageId,[J.userOpenId])})()}}var nX=O(()=>{v$();t0();t();f();T6()});class aX{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new U1({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=XQ($),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,x6(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};取消请求失败:${x6(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=x6(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,`登录进程关闭失败:${x6(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 x6($){return $ instanceof Error?$:Error(String($))}var p1;var pZ=O(()=>{k$();m0();f();p1=new aX});function oX($){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 rX=O(()=>{m0();k$()});class d2{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=jD){let Y=await J.sendCard($,K$(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new d2(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=j9($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=j9($);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:_9($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var jD;var sX=O(()=>{t();v$();S0();g2();jD={sendCard:c,convertMessageToCard:G$,recordCardCreated:Z$,replaceElementChecked:A0,patchSettingsChecked:R0,dispose:J$}});var uZ={};N$(uZ,{settleCodexAccountCards:()=>cZ,runCodexNamedHi:()=>qD,runCodexAccountCommand:()=>PD});import{createHash as LD}from"node:crypto";function A9($,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 tX($,Z){if(!await c($.chatId,K$(A9(Z))))throw Error("Codex 错误卡片发送失败")}async function qD($,Z){let J=await d2.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(A9(Y,Z))}}async function cZ(){let Z=(await Promise.allSettled([...c1.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function PD($,Z,J,Y,Q){if(Z==="reset"){await FD($,J,Q);return}let V={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let z=p1.pending(V);if(!J&&z.length!==1)throw Error(z.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?k.find(J).id:z[0];await p1.cancel(W,V),await c1.get(W)}catch(z){await tX($,z)}return}let H=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,X=await d2.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(c1.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():H0("codex-sub")?.defaultModel;if(!j)throw Error("Codex 模型 MISS,无法计算调度顺序");let q=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,P=await A8.choose({model:j,effort:q}),D=oX(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")b1($.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($8(z.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(c1.has(z.id))throw Error("登录结果正在更新,请稍等");let W=await p1.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 p1.cancel(z.id,V),_}let G=(async()=>{let _;try{_=await W.done}catch(q){await X.finish(A9(q,z.name));return}await X.update({phase:"checking",flow:"login",name:z.name,message:"授权完成,正在读取模型…"});let j;try{await M2();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}`})})();c1.set(z.id,G);let B=()=>{if(c1.get(z.id)===G)c1.delete(z.id)};G.then(B,(_)=>{K(`codex-login: terminal card write failed: ${_}`),B()})}catch(z){K(`codex-${Z}: ${z}`),await X.finish(A9(z,H))}}async function FD($,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(a0($.proc))}catch(W){K(`codex-reset: ${W}`),await tX($,W);return}let Q=await d2.open($.chatId,{phase:"checking",name:Y.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let W=LD("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await rQ(Y.id,W)}catch(W){K(`codex-reset: ${W}`),await Q.finish(A9(W,Y.name));return}let H=DD[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(`
221
+ `);await Q.finish({...H,name:Y.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var c1,DD;var S6=O(()=>{t();m0();pZ();Y0();rX();y3();sX();g2();f();k$();c1=new Map;DD={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});function P0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function lZ($,Z){let J=$.agent==="claude"?w7.filter((Q)=>Q!=="default"):$.agent==="codex"?[...Z3]:["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 C6($,Z){let J=$.modelSelection,Y=new Set(P0(Z.hidden_models)),Q=[...new Set([...P0(Z.custom_models),...J?[]:P0(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",...lZ($,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 u1=O(()=>{B0();F1()});import{homedir as MD}from"node:os";function Zz($,Z=$z){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 eX($){return typeof $==="string"&&UD.includes($)?$:null}async function b6($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (j2(),T3)),J=new Z({workDir:MD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Y)=>K(`Claude model catalog MISS: ${Y.message}`));try{let Y=await Zz(J.listModels());if(!Y.length)throw Error("Claude SDK model catalog is empty");return Y.map((Q)=>({model:Q.model.replace(/^claude:/,""),display:Q.displayName,efforts:Q.supportedReasoningEfforts.map((V)=>V.reasoningEffort),defaultEffort:Q.defaultReasoningEffort}))}finally{await J.kill()}}async function Jz($="default"){let Z=new U1({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 Zz(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)=>eX(W?.reasoningEffort)).filter((W)=>W!==null);if(!X.length)continue;let z=eX(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 Yz($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,V=await $0(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout($z)});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:i2,defaultEffort:"max"}})}var $z=1e4,UD,i2;var n2=O(()=>{f0();k$();f();UD=["none","minimal","low","medium","high","xhigh","max","ultra"];i2=["max","xhigh","high","medium","low"]});import{existsSync as AD}from"node:fs";import{join as OD}from"node:path";function Qz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function RD($){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(Qz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(Qz($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function Vz($){return $===u||AD(OD(k.home($),"auth.json"))}var Hz=O(()=>{k0();Y0();k$();n2();f();m0();u1();M0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let H=Vz(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=Vz(V),!W.enabled){W.models=[],W.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}W.modelCatalogState={status:"loading",updatedAt:null};try{if(W.models=await Jz(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=r0(G);return Object.assign(B,h.codex.env),k.env(V,B)},resolveSpawnModel(G){return G},async readUsage(){return RD(await A1(V))}};return W},Y=J(u);Y.forAccount=(V)=>{if(V===u)return Y;let H=k.revision(V),X=Z.get(V);if(X?.revision===H)return X.source;let z=C6(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!==u).map((V)=>Y.forAccount(V.id).refreshModels())])},Y}})});function TD($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function k6($,Z,J){try{let Y=await $0(TD($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(ND)});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 ND=15000;var dZ=O(()=>{f0();f()});function Xz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function ED($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function zz($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function xD($){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 SD($){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 iZ($){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(Xz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(Xz($.weekly,"weekly","周额度"));if($.monthly)Z.push(ED($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var nZ=O(()=>{Y0();q9();n2();S4();dZ();f();M0({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=SD($.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 Yz(J,Y),G=[...new Set([...zz($.models),...zz($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:i2,defaultEffort:"max",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=xD(X.models.map((B)=>B.model));for(let B of X.models){let _=B2("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={...r0(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 z8("glm",z)},async verifyModel(z){return k6(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return iZ(await L9(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
221
222
  \`\`\`
222
223
  glm-setup <base_url> <token>
223
- \`\`\``,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(!p1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var tX=O(()=>{Y0();a2();M0({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 b6(),!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 MD(){let $=Object.fromEntries(P8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function AD($){if(!$.subscriptionType?.trim())throw Object.assign(Error("Claude Code 订阅未登录;请在本机运行 claude auth login,完成后发送 md 刷新"),{code:"CLAUDE_SUBSCRIPTION_AUTH_MISSING"});if($.apiProvider!=="firstParty"||$.apiKeySource&&$.apiKeySource!=="none")throw Error("Claude Code 当前认证不是第一方订阅;请检查本机登录方式和托管设置")}var eX=O(()=>{_0();f();Y0();a2();i1();M0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=MD(),J=$.model?.trim(),Y={id:"claude-sub",kind:"claude-subscription",agent:"claude",display:$.display?.trim()||"Claude Code 订阅",enabled:!0,models:[],defaultModel:J??"",modelCatalogState:{status:"idle",updatedAt:Date.now()},settingSources:["user","project","local"],claudeSettings:Z,validateClaudeAccount:AD,spawnEnv(Q){return{...e0(Q),...Z.env}},resolveSpawnModel(Q){return Q},async refreshModels(){Y.enabled=!0,Y.models=[],Y.modelCatalogState={status:"loading",updatedAt:null};try{let Q=await b6({settingSources:["user"],settings:Z,transformEnv:Y.spawnEnv,validateAccount:Y.validateClaudeAccount,tokenSourceId:Y.id});if(!Q.length)throw Error("Claude Code 订阅模型目录为空");let V=[...F0($.custom_models),...F0($.models)];if(J&&!Q.some((H)=>H.model===J)&&!V.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let H=Q.find((X)=>X.model===(J??Q[0].model));if(!U0($.effort)||H&&!H.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(H)H.defaultEffort=$.effort}Y.defaultModel=J??Q[0].model,Y.models=Q,Y.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(Q){let V=Q instanceof Error?Q.message:String(Q);if(K(`claude-sub refreshModels MISS: ${V}`),Q?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")Y.enabled=!1;Y.modelCatalogState={status:Y.enabled?"failed":"disabled",updatedAt:Date.now(),error:V}}},async readUsage(){return{state:"not_applicable",windows:[]}}};return Y}})});function $z($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function RD($){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 ND($){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 TD($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function ED($,Z){let J=new URL($).origin,Y=await $0(`${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:n2,defaultEffort:"high"}))}async function uZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await $0(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(xD)});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 OD="https://api.deepseek.com/anthropic",xD=1e4;var lZ=O(()=>{h0();Y0();a2();x4();mZ();f();M0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||OD,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,V=$.model?.trim()||void 0,H=ND($.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 ED(J,Y),G=[...new Set([...$z($.models),...$z($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:n2,defaultEffort:"high",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=RD(X.models.map((B)=>B.model));for(let B of X.models){let _=q2("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={...e0(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 G8("deepseek",z)},async verifyModel(z){return C6(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return uZ(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
224
+ \`\`\``,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 Wz=O(()=>{Y0();n2();M0({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 b6(),!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 CD(){let $=Object.fromEntries(L8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function bD($){if(!$.subscriptionType?.trim())throw Object.assign(Error("Claude Code 订阅未登录;请在本机运行 claude auth login,完成后发送 md 刷新"),{code:"CLAUDE_SUBSCRIPTION_AUTH_MISSING"});if($.apiProvider!=="firstParty"||$.apiKeySource&&$.apiKeySource!=="none")throw Error("Claude Code 当前认证不是第一方订阅;请检查本机登录方式和托管设置")}var Gz=O(()=>{B0();f();Y0();n2();OZ();u1();M0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=CD(),J=$.model?.trim(),Y,Q={id:"claude-sub",kind:"claude-subscription",agent:"claude",display:$.display?.trim()||"Claude Code 订阅",enabled:!0,models:[],defaultModel:J??"",modelCatalogState:{status:"idle",updatedAt:Date.now()},settingSources:["user","project","local"],claudeSettings:Z,validateClaudeAccount:bD,spawnEnv(V){return{...r0(V),...Z.env}},resolveSpawnModel(V){return V},async refreshModels(){Q.enabled=!0,Q.models=[],Q.modelCatalogState={status:"loading",updatedAt:null};try{let V=await b6({settingSources:["user"],settings:Z,transformEnv:Q.spawnEnv,validateAccount:Q.validateClaudeAccount,tokenSourceId:Q.id});if(!V.length)throw Error("Claude Code 订阅模型目录为空");let H=[...P0($.custom_models),...P0($.models)];if(J&&!V.some((X)=>X.model===J)&&!H.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let X=V.find((z)=>z.model===(J??V[0].model));if(!D0($.effort)||X&&!X.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(X)X.defaultEffort=$.effort}Q.defaultModel=J??V[0].model,Q.models=V,Q.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){let H=V instanceof Error?V.message:String(V);if(K(`claude-sub refreshModels MISS: ${H}`),V?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")Q.enabled=!1;Q.modelCatalogState={status:Q.enabled?"failed":"disabled",updatedAt:Date.now(),error:H}}},readUsage(){return Y??=WX({settingSources:["user"],settings:Z,transformEnv:Q.spawnEnv,validateAccount:Q.validateClaudeAccount,tokenSourceId:Q.id}).finally(()=>{Y=void 0}),Y}};return Q}})});function Kz($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function yD($){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 vD($){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 wD($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function fD($,Z){let J=new URL($).origin,Y=await $0(`${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:i2,defaultEffort:"high"}))}async function aZ($,Z){let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}try{let Y=await $0(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(hD)});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 kD="https://api.deepseek.com/anthropic",hD=1e4;var oZ=O(()=>{f0();Y0();n2();S4();dZ();f();M0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||kD,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,V=$.model?.trim()||void 0,H=vD($.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 fD(J,Y),G=[...new Set([...Kz($.models),...Kz($.custom_models)])].filter((B)=>!z.some((_)=>_.model.toLowerCase()===B.toLowerCase())).map((B)=>({model:B,display:B,efforts:i2,defaultEffort:"high",origin:"custom"}));if(X.models=[...z,...G],!V)X.defaultModel=yD(X.models.map((B)=>B.model));for(let B of X.models){let _=B2("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={...r0(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 z8("deepseek",z)},async verifyModel(z){return k6(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return aZ(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
224
225
  \`\`\`
225
226
  deepseek-setup <api_key>
226
227
  \`\`\`
227
- 默认官方 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(!TD(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function n1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var dZ;var Zz=O(()=>{dZ=[{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 G1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function nZ($){return $ instanceof Error?$.message:String($)}function Jz($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function o2($){return $.replace(/\[1m\]$/,"")}function k6($){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 Qz($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await $0(`${k6($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(bD)});if(!Y.ok){let Q=await Y.text(),V="";if(Q.trim().startsWith("{"))try{let H=JSON.parse(Q);if(G1(H)&&G1(H.error)&&typeof H.error.message==="string")V=H.error.message}catch{}throw new aZ(Y.status,V.replaceAll(Z,"[redacted]"))}return Y.json()}async function CD($,Z){let J=await Qz($,Z,"models/user");if(!G1(J)||!Array.isArray(J.data))throw Error("OpenRouter models: data 数组缺失");let Y=[],Q=new Set;for(let V of J.data){if(!G1(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!G1(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(n1(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Q.has(V.id))continue;let H=G1(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"&&U0(_)))]:["default"],W=dZ.find((_)=>_.model===V.id),G=W?z.includes(W.effort)?W.effort:null:z[0]==="default"?"default":U0(H?.default_effort)&&z.includes(H.default_effort)?H.default_effort:null,B=q2("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 Yz($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function kD($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await Qz($,Z,"credits");if(!G1(J)||!G1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!Yz(Y)||!Yz(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=nZ(J);return K(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof aZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var SD="https://openrouter.ai/api",bD=1e4,iZ,aZ;var Vz=O(()=>{h0();_0();Y0();x4();f();Zz();iZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};aZ=class aZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};M0({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()||SD,V=$.model?.trim()||"",H=$.models===void 0?dZ.map((z)=>z.model):Jz($.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(n1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let W=X.modelSelection.availableModels.find((G)=>o2(G.model)===o2(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 CD(Q,Y),W=z.find((B)=>B.model===o2(V));if(V&&!W)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!U0($.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===o2(B));if(!_)return{model:B,display:B,efforts:[],defaultEffort:null,unavailableReason:n1(B)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:B}});X.models=G,X.modelSelection.availableModels=z,X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let W=nZ(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(n1(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let B=e0(z);B.ANTHROPIC_BASE_URL=k6(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(iZ))B[_]=G;for(let _ of Jz($.slots)){let j=_.indexOf("="),q=_.slice(0,j).trim(),P=_.slice(j+1).trim();if(j<1||!Object.hasOwn(iZ,q)||!P)throw Error(`OpenRouter slots 无效: ${_}`);if(n1(P)||!X.modelSelection.availableModels.some((D)=>!D.unavailableReason&&o2(D.model)===o2(P)))throw Error(`OpenRouter slot 模型不在账号目录中: ${P}`);if(X.modelEnvironmentRevision(P)!==X.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${P}`);B[iZ[q]]=P}return B},resolveSpawnModel(z){if(n1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return kD(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:k6(Z[0])}:{}}}}catch(J){return{error:nZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=k6(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var Hz=O(()=>{Y0();_0();D4();V0();lZ();i1();M0({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=b4(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 z2({cwd:Q2,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...F0($.models),...F0($.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 F2(Y).find((V)=>V.model===Q)?.model},readUsage(){return Z?uZ(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 oZ($){let Z=new URL($);if(!p1(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 yD($,Z){let J=await $0(`${$}/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 Xz=O(()=>{h0();y0();_0();Y0();D4();V0();P9();cZ();i1();M0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=h.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&p1(Y)?{api_key:J,base_url:oZ(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=oZ($.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=b4(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 yD(Y,J),z=[...X];for(let G of[...F0($.models),...F0($.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 z2({cwd:Q2,env:H.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");H.models=z.map((G)=>{let B=W.find((P)=>P.model===G.model),_=gZ(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 F2(H).find((z)=>z.model===X&&!z.unavailableReason)?.model},async readUsage(){return J?pZ(await q9(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:oZ(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 Wz={};E$(Wz,{tokenSourceSpawnRevision:()=>zz,buildTokenSourcesFromConfig:()=>rZ});import{createHash as wD}from"node:crypto";function rZ(){E3();let $=DZ(),Z=M2().map((V)=>{let H=V.configSectionId?(h.token_sources??{})[V.configSectionId]??{}:{},X=V.detect?.fromSettingsEnv($)??null,z=S6(V.build(H,X),H);return z.spawnRevision=zz(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"&&H.kind!=="claude-subscription");J.enabled=!V,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let V of Z)N3(V);let Q=Z.find((V)=>V.enabled&&h.token_sources?.[V.id]?.default===!0)??Z.find((V)=>V.enabled);if(Q)T3(Q.id);return Z.length}function zz($,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 wD("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var sZ=O(()=>{y0();Y0();P9();i1();oX();cZ();tX();eX();lZ();Vz();Hz();Xz()});import{readFileSync as vD}from"node:fs";function fD($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function hD($,Z){let J=[`[token_source.${$}]`],Y=(Q,V)=>{if(V!==void 0)J.push(`${Q} = "${fD(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(`
228
- `)}function ID($,Z){let J=vD(x0,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
229
- `),V=!1,H=n9().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();I0(x0,X.join(`
228
+ 默认官方 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(!wD(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 rZ;var Bz=O(()=>{rZ=[{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 tZ($){return $ instanceof Error?$.message:String($)}function _z($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function a2($){return $.replace(/\[1m\]$/,"")}function y6($){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 Lz($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await $0(`${y6($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(gD)});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 eZ(Y.status,V.replaceAll(Z,"[redacted]"))}return Y.json()}async function mD($,Z){let J=await Lz($,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"&&D0(_)))]:["default"],W=rZ.find((_)=>_.model===V.id),G=W?z.includes(W.effort)?W.effort:null:z[0]==="default"?"default":D0(H?.default_effort)&&z.includes(H.default_effort)?H.default_effort:null,B=B2("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 jz($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function pD($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};try{let J=await Lz($,Z,"credits");if(!H1(J)||!H1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!jz(Y)||!jz(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=tZ(J);return K(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof eZ&&J.status===429?"rate_limited":"network",windows:[],reason:Y}}}var ID="https://openrouter.ai/api",gD=1e4,sZ,eZ;var qz=O(()=>{f0();B0();Y0();S4();f();Bz();sZ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};eZ=class eZ extends Error{status;constructor($,Z){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$}};M0({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()||ID,V=$.model?.trim()||"",H=$.models===void 0?rZ.map((z)=>z.model):_z($.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)=>a2(G.model)===a2(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 mD(Q,Y),W=z.find((B)=>B.model===a2(V));if(V&&!W)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!D0($.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===a2(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=tZ(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=r0(z);B.ANTHROPIC_BASE_URL=y6(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(sZ))B[_]=G;for(let _ of _z($.slots)){let j=_.indexOf("="),q=_.slice(0,j).trim(),P=_.slice(j+1).trim();if(j<1||!Object.hasOwn(sZ,q)||!P)throw Error(`OpenRouter slots 无效: ${_}`);if(l1(P)||!X.modelSelection.availableModels.some((D)=>!D.unavailableReason&&a2(D.model)===a2(P)))throw Error(`OpenRouter slot 模型不在账号目录中: ${P}`);if(X.modelEnvironmentRevision(P)!==X.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${P}`);B[sZ[q]]=P}return B},resolveSpawnModel(z){if(l1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return pD(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:y6(Z[0])}:{}}}}catch(J){return{error:tZ(J)}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=y6(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var Pz=O(()=>{Y0();B0();P4();V0();oZ();u1();M0({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=C4(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 Q2({cwd:$2,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...P0($.models),...P0($.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(K0)||!K0(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&&(!K0(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?aZ(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 $J($){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 cD($,Z){let J=await $0(`${$}/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 Dz=O(()=>{f0();k0();B0();Y0();P4();V0();q9();nZ();u1();M0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=h.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:$J(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=$J($.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=C4(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 cD(Y,J),z=[...X];for(let G of[...P0($.models),...P0($.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 Q2({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),_=lZ(H,$),j=B?B.efforts.filter(K0):_.efforts,q=$.effort?.trim()||B?.defaultEffort||_.defaultEffort;return{...G,display:B?.display??G.display,efforts:j,defaultEffort:K0(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?iZ(await L9(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:$J(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 Mz={};N$(Mz,{tokenSourceSpawnRevision:()=>Fz,buildTokenSourcesFromConfig:()=>ZJ});import{createHash as uD}from"node:crypto";function ZJ(){S3();let $=AZ(),Z=D2().map((V)=>{let H=V.configSectionId?(h.token_sources??{})[V.configSectionId]??{}:{},X=V.detect?.fromSettingsEnv($)??null,z=C6(V.build(H,X),H);return z.spawnRevision=Fz(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"&&H.kind!=="claude-subscription");J.enabled=!V,J.modelCatalogState={status:J.enabled?"idle":"disabled",updatedAt:Date.now()}}for(let V of Z)E3(V);let Q=Z.find((V)=>V.enabled&&h.token_sources?.[V.id]?.default===!0)??Z.find((V)=>V.enabled);if(Q)x3(Q.id);return Z.length}function Fz($,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 uD("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var JJ=O(()=>{k0();Y0();q9();u1();Hz();nZ();Wz();Gz();oZ();qz();Pz();Dz()});import{readFileSync as lD}from"node:fs";function dD($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function iD($,Z){let J=[`[token_source.${$}]`],Y=(Q,V)=>{if(V!==void 0)J.push(`${Q} = "${dD(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(`
229
+ `)}function nD($,Z){let J=lD(E0,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
230
+ `),V=!1,H=d9().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();h0(E0,X.join(`
230
231
  `)+`
231
232
 
232
- `+hD($,G)+`
233
- `)}function y6($){let Z=Gz.then($);return Gz=Z.then(()=>{},()=>{}),Z}async function w6($,Z){ID($,Z),iY(),rZ(),await k4()}function Kz($,Z){return y6(()=>w6($,Z))}function Bz($,Z,J,Y="default"){return y6(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=h.token_sources[$],z=Q.modelSelection.mode==="catalog",W=F0(X?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...W,Z])]:W.filter((_)=>_!==Z)).join(",")}:{models:H.join(",")};await w6($,G);let B=H0($,Y);if(B?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${B?.modelCatalogState?.error??"MISS"}`)})}function _z($,Z,J="default"){return y6(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=h.token_sources[$];await w6($,{custom_models:[...F0(H?.custom_models),Y].join(",")});let X=H0($,J);if(X?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${X?.modelCatalogState?.error??"MISS"}`)})}function jz($,Z,J="default"){return y6(async()=>{let Y=H0($,J),Q=Y?.modelSelection?.availableModels.find((W)=>W.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=h.token_sources[$]??{},H=(W)=>W?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),X={custom_models:F0(V.custom_models).filter((W)=>!H(W)).join(","),hidden_models:F0(V.hidden_models).filter((W)=>!H(W)).join(","),...V.models!==void 0?{models:F0(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 w6($,X);let z=H0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var Gz;var tZ=O(()=>{V0();y0();sZ();Y0();S0();i1();Gz=Promise.resolve()});var eZ={};E$(eZ,{runTokenSourceSetup:()=>mD,onTokenSourceEnable:()=>gD});async function gD($,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=M2().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 c($.chatId,H$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await E($.chatId,"请在运行 Lodestar 的本机执行 `claude auth login` 登录 Claude 订阅,完成后发送 `md` 刷新。");else if(J.kind==="claude-native")await E($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function mD($,Z,J){let Y=M2().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 Kz(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 $J=O(()=>{t();Y0();tZ();E2()});async function Lz($,Z,J="",Y){let Q=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Q){let{runCodexNamedHi:G}=await Promise.resolve().then(() => (x6(),IZ));return await G($,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:G}=await Promise.resolve().then(() => (x6(),IZ));return await G($,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;let X=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(X)return await $.runFileDeliveryCommand((X[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let z=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(z){let{runTokenSourceSetup:G}=await Promise.resolve().then(() => ($J(),eZ));return await G($,z[1].trim().toLowerCase(),(z[2]??"").trim()),!0}let W=pD.get(Z.trim().toLowerCase());if(!W)return!1;switch(W){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(() => (E2(),ZV));if(!await c($.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":{let G=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let _=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!_,onStatus:(j)=>$.setStatusCard(_,j)}),await $.closeStatusCard(_,"\uD83D\uDED1 已取消额度恢复")}catch(j){throw await $.closeStatusCard(_,`❌ ${R(j)}`),j}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(G)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await E($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let _=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(_)await $.closeStatusCard(_,"⚪ 无正在执行的 turn");else await E($.chatId,"⚪ 当前没有正在执行的 turn");return!0}K(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let B=new Set;for(let[_,j]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(j)k0(_,j);l0(_,"CrossMark"),B.add(_)}for(let _ of $.pendingMidTurnMsgs)if(_.msgId&&!B.has(_.msgId))l0(_.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} 未确认终止: ${R(D)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${B} 停止收尾失败: ${R(D)}`}finally{try{await $.closeStatusCard(j,P)}catch(D){K(`session "${$.sessionName}": kill status card close failed: ${R(D)}`),await w($.chatId,`${P}
234
- ⚠️ kill 状态卡片终态写入失败: ${R(D)}`)}}if(q&&!j)await w($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let G=$.lastSessionId?R0($.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 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 pD;var qz=O(()=>{t();f();pD=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 lD($){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 dD($,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 iD($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=l8($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=d8($.contextWindow);return` · \uD83E\uDDE0 ${pV(Z,J)} (${i8(Z,J)})`}async function Pz($){$.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?R0(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=lD(J),z=dD(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,uD),B=W.threadId?` thread=${R0(W.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${B}${iD(G)}`))}catch(W){if(X.cancel(),W instanceof M1)await H($.withModel(`ⓘ ${W.message}`));else await H(`❌ 上下文压缩失败: ${R(W)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var uD=1500;var Dz=O(()=>{_0();t()});import{randomUUID as aD}from"node:crypto";function oD($){let Z=$.currentTokenSource();return y$().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 JJ($,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 Fz($){await k4();let Z=aD(),J=oD($);$.modelPanels.set(Z,{models:[]});let Y=await c($.chatId,a5({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 YJ($,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=JJ($,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}),v6($,V,Y,0)}async function v6($,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/ZJ));if(!Number.isInteger(Y)||Y<0||Y>=V)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*ZJ,(Y+1)*ZJ),Q.page=Y,Q.totalPages=V,{ok:!0,message:"",card:o5({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 Uz($,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:JJ($,Q,V),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),v6($,Z,J,0)}async function Mz($,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=[...K$.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 jz(J,Y,$.codexAccountId());else await Bz(J,Y,Q,$.codexAccountId());for(let z of K$.all)for(let[W,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||W!==Z))z.modelPanels.delete(W);return{...await YJ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(X){return{ok:!1,message:`模型列表更新失败:${R(X)}`}}}async function Az($,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:s5($.sessionName,Q.display,V)}}async function Oz($,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 J$(Y.cardMessageId),d0(j,1),q=await O0(j,N.modelPanel,_,{notifyCardFailure:!1}),!q)throw Error("model panel replace rejected");if(P=await D0(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 D0(j,{config:{streaming_mode:!1}})}catch(D){K(`model-custom: streaming-off retry MISS (${D?.message??D})`)}if(q&&P)try{await v0(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}
235
- 请重新发送 model 打开面板。`;if(!await w($.chatId,P))K(`model-custom: visible fallback send MISS (${j})`);return!1},z=(_)=>X(g2(!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(g2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await _z(V.id,Q,$.codexAccountId())}catch(_){return K(`model-custom: config/refresh MISS (${R(_)})`),await z(`配置写入或模型刷新失败:${R(_)}`),!0}K(`model-custom: ${V.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let _ of K$.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=JJ($,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(g2(!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?L6({sessionName:$.sessionName,provider:B.provider,model:B.model,effort:B.efforts[0].effort,scope:Nz($,B.provider??"codex")}):g2(!0,Q,_.message),_.message),!0}return await X(j6({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:B}),`✅ 模型 ${Q} 已补录成功。`),!0}async function Rz($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:_6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:_6($.sessionName)}}function rD($,Z){return _$(Z?.provider)?Z.provider:W2($)}function Nz($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${j$(Z)} 时使用。`}async function Tz($,Z,J="",Y="",Q=null){let V=Z.trim();if(!V)return await E($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=rD(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 QJ($,V,X.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:r5({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function QJ($,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=_$(V)?V:W?.models.find((M)=>M.model===H)?.provider??W2(H);if(G==="dsh"){if(!B0(X))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!U0(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!s0(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:`${j$(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:`当前已是 ${j$(G)} · ${H} / ${B}`,card:B6({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 后再切换到 ${j$(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 sY($.proc.setModelSettings(S,B),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,B,_.sourceId);let M=Nz($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${j$(G)} · ${H} / ${B}`,card:B6({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:M})}}catch(M){let S=`模型切换失败: ${R(M)}`;return K(`session "${$.sessionName}": set model settings failed: ${R(M)}`),await E($.chatId,`❌ ${S}`),{ok:!1,message:S}}}var ZJ=20;var Ez=O(()=>{_0();VJ();Y0();tZ();O1();_0();Q$();v$();t();f()});import{createHash as tD}from"node:crypto";function eD($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function a1($="default"){return $F(y$().map((Z)=>Z.forAccount?.($)??Z))}function $F($){let Z=[],J=[];for(let Y of $)ZF(Y,Z,J);return{catalogGeneration:tD("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function ZF($,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(JF($,Q,Y))}function JF($,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:eD($.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:xz($.defaultModel)===xz(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function xz($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var f6=O(()=>{Y0()});import{randomUUID as YF}from"node:crypto";async function Sz($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}kz(),await A2();let J=`agents_${YF()}`;if(N9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await c($.chatId,Cz(J)))await w($.chatId,"❌ agents 面板发送失败")}function bz($,Z,J){let Y=HF($,J),Q=Number(Z);if(!Number.isInteger(Q))return XF("无效页码");let V=VF(Y.codexAccountId);return Y.page=Math.max(0,Math.min(V-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:Cz($)}}function Cz($){let Z=N9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=a1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/h6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*h6;return GZ({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+h6),failures:J.sourceFailures})}function VF($){return Math.max(1,Math.ceil(a1($).identities.length/h6))}function HF($,Z){kz();let J=N9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function XF($){return{ok:!1,message:$,card:z1({title:"agents",message:$,ok:!1})}}function kz(){let $=Date.now()-QF;for(let[Z,J]of N9)if(J.createdAt<$)N9.delete(Z)}var h6=8,QF=1800000,N9;var yz=O(()=>{Q$();t();f6();Y0();N9=new Map});var zJ={};E$(zJ,{withTasklistLifecycleLock:()=>p6,tasklistNameForProject:()=>m6,reconcileTasklistDeletions:()=>KF,isTasklistAlreadyDeletedError:()=>wz,getTasklistBinding:()=>m$,enableTasklist:()=>HJ,deleteTasklistRemoteIdempotently:()=>vz,deleteTasklist:()=>XJ});import{existsSync as WF,readFileSync as GF}from"node:fs";function m6($){return`${$}[lodestar]`}function m$($){let Z=g$.get($);return Z?r2(Z):null}async function p6($,Z){let J=I6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),V=J.catch(()=>{}).then(()=>Q);I6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Y(),I6.get($)===V)I6.delete($)}}function wz($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function vz($,Z=u3){try{return await Z($),"deleted"}catch(J){if(wz(J))return"already_deleted";throw J}}async function HJ($,Z){return await p6($,async()=>{let J=m$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=m6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await p3(Z),V=await c3(Y,Q),H={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Q,createdAt:V.createdAt};return g6($,H),r2(H)})}async function XJ($,Z){return await p6($,async()=>{let J=m$($);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},g6($,J);return await fz($,Z)})}async function fz($,Z){let J=m$($);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,g6($,J);try{if(await vz(Z)==="already_deleted")K(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(g$);return Q.delete($),hz(Q),g$.delete($),r2(J)}catch(Y){let Q=m$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),g6($,Q);throw Y}}async function KF(){let $=[...g$.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await p6(J.projectName,()=>fz(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 BF(){if(!WF(C9))return;try{let $=JSON.parse(GF(C9,"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:_F(Y.deleting)};g$.set(Z,Q)}K(`tasklist: loaded ${g$.size} project bindings`)}catch($){K(`tasklist: load map failed: ${$}`)}}function _F($){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 g6($,Z){let J=new Map(g$);J.set($,r2(Z)),hz(J),g$.set($,r2(Z))}function hz($=g$){let Z={};for(let[J,Y]of $)Z[J]=r2(Y);s(C9,Z)}function r2($){return JSON.parse(JSON.stringify($))}var g$,I6;var WJ=O(()=>{V0();t();f();S0();g$=new Map,I6=new Map;BF()});function K1($,Z,J=!1){let Y=$.worktreeProjectName();return zZ({projectName:Y,tasklistName:m6(Y),binding:m$(Y),notice:Z,confirmDelete:J})}async function Iz($){if(!await c($.chatId,K1($)))await w($.chatId,"❌ task 面板发送失败")}async function gz($){let Z=$.worktreeProjectName();try{let J=m$(Z),Y=await HJ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:K1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${R(J)}`;return K(`session "${$.sessionName}": tasklist enable failed: ${R(J)}`),{ok:!1,message:Y,card:K1($,{type:"error",content:`❌ ${Y}`})}}}function mz($,Z){let J=$.worktreeProjectName(),Y=m$(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:K1($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:K1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:K1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function pz($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let V=`已删除 ${(await XJ(J,Y)).name}`;return{ok:!0,message:V,card:K1($,{type:"success",content:`✅ ${V}`})}}catch(Q){let V=`删除失败: ${R(Q)}`;return K(`session "${$.sessionName}": tasklist delete failed: ${R(Q)}`),{ok:!1,message:V,card:K1($,{type:"error",content:`❌ ${V}`})}}}var cz=O(()=>{Q$();t();f();WJ()});import{open as LF}from"node:fs/promises";import{basename as qF}from"node:path";function GJ($){if(typeof $!=="string"||!$.trim())throw Error("云空间链接 MISS");let Z=new URL($);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("云空间链接无效");return Z.href}function p$($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class uz{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:$0,getToken:U$,retry:x1,wait:(Z)=>new Promise((J)=>setTimeout(J,Z)),intervalMs:250}){this.deps=$}request($,Z,J="GET",Y,Q){let V=this.queue.then(()=>this.deps.retry($,async()=>{Q?.throwIfAborted();let H=await this.deps.getToken(),X=Y?.(),z=X instanceof FormData,W=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(W>0)await this.deps.wait(W);Q?.throwIfAborted(),this.lastStartedAt=Date.now();let G=AbortSignal.timeout(FF),B=new AbortController,_=()=>B.abort(G.reason),j=()=>B.abort(Q.reason);G.addEventListener("abort",_,{once:!0}),Q?.addEventListener("abort",j,{once:!0});let q=B.signal;try{let P=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${H}`,...!z&&X!==void 0?{"Content-Type":"application/json"}:{}},...X!==void 0?{body:z?X:JSON.stringify(X)}:{},signal:q});return(await x2(P,$)).data}catch(P){if(q.aborted&&q.reason?.name==="TimeoutError")throw q.reason;throw P}finally{G.removeEventListener("abort",_),Q?.removeEventListener("abort",j)}}));return this.queue=V.then(()=>{},()=>{}),V}async createFolder($,Z){let J=await this.request("创建交付文件夹","/drive/v1/files/create_folder","POST",()=>({name:$,folder_token:""}),Z);return{token:p$(J?.token,"交付文件夹"),url:GJ(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return p$(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Y=p$(J?.token,"群文件夹");if(Y!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Y,url:GJ($.url),name:p$(J?.name,"群文件夹名称")}}async renameFolder($,Z,J){try{await this.request("同步群文件夹名称",`/drive/v1/files/${encodeURIComponent($.token)}?type=folder`,"PATCH",()=>({new_title:Z}),J)}catch(Q){if(Q instanceof D$&&Q.code===99991672)throw new D$("同步群文件夹名称需要应用身份权限 drive:file:upload(飞书错误码 99991672)",Q.status,Q.code);throw Q}let Y=await this.getFolder($,J);if(Y.name!==Z)throw Error("群文件夹名称更新未生效");return Y}async grantFolderAccess($,Z,J,Y){p$(Z,"交付群"),p$(J,"交付发起人");let Q=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let H of[{member_type:"openid",member_id:J,perm:"full_access",type:"user"},{member_type:"openchat",member_id:Z,perm:"view",type:"chat"}])await this.request("设置交付文件夹权限",Q,"POST",()=>H,Y);let V=await this.request("核对交付文件夹权限",Q,"GET",void 0,Y);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[H,X,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((G)=>G.member_type===H&&G.member_id===X)?.perm!==z)throw Error(`交付文件夹权限未生效:${H} / ${z}`)}async closeFileLinkSharing($,Z){p$($,"交付文件");let J=`/drive/v2/permissions/${encodeURIComponent($)}/public?type=file`;if(await this.request("关闭交付文件链接分享",J,"PATCH",()=>({link_share_entity:"closed"}),Z),(await this.request("核对交付文件链接分享",J,"GET",void 0,Z))?.permission_public?.link_share_entity!=="closed")throw Error("交付文件链接分享未关闭,不能发布交付链接")}async uploadFile($,Z,J,Y){Y?.throwIfAborted();let Q=await LF($,"r");try{let V=await Q.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let H=qF($),X={file_name:H,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=PF){let q=await Q.readFile(),P=await Q.stat();if(q.length!==V.size||P.mtimeMs!==V.mtimeMs||P.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let D=new FormData;for(let[T,U]of Object.entries(X))D.append(T,String(U));return D.append("file",new Blob([Uint8Array.from(q)]),H),D},Y)}else{let q=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>X,Y),P=p$(q?.upload_id,"分片上传事务"),D=q?.block_size,T=q?.block_num;if(!Number.isSafeInteger(D)||D<=0||D>DF||!Number.isSafeInteger(T)||T!==Math.ceil(V.size/D))throw Error("云空间返回的分片策略无效");for(let A=0;A<T;A++){Y?.throwIfAborted();let M=Math.min(D,V.size-A*D),S=Buffer.alloc(M),b=0;while(b<M){let v=await Q.read(S,b,M-b,A*D+b);if(!v.bytesRead)throw Error("交付文件在分片读取时发生变化");b+=v.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let v=new FormData;return v.append("upload_id",P),v.append("seq",String(A)),v.append("size",String(M)),v.append("file",new Blob([Uint8Array.from(S)]),H),v},Y)}let U=await Q.stat();if(U.size!==V.size||U.mtimeMs!==V.mtimeMs||U.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:P,block_num:T}),Y)}let W=p$(z?.file_token,"已上传文件"),G={token:W,url:"",name:H,bytes:V.size};J(G),await this.closeFileLinkSharing(W,Y);let B=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:W,doc_type:"file"}],with_url:!0}),Y),_=B?.metas?.find((q)=>q.doc_token===W&&q.doc_type==="file");if(B?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let j={...G,url:GJ(_.url)};return J(j),j}finally{await Q.close()}}}var PF=20971520,DF=20971520,FF=60000,o1;var lz=O(()=>{h0();t();E8();o1=new uz});import{randomUUID as dz}from"node:crypto";import{basename as UF}from"node:path";class KJ{deps;snapshot;queue=Promise.resolve();folderPromise;finishPromise;persistenceError;abort=new AbortController;constructor($,Z){this.deps=Z;if(!$.chatId.trim()||!$.managerOpenId.trim())throw Error("无法确认交付群或本次交付发起人");this.snapshot={...$,version:1,id:dz(),folderAccessReady:!1,files:[]}}add($){if(this.finishPromise)throw Error("本次文件交付已结束");if(this.abort.signal.throwIfAborted(),this.snapshot.files.some((J)=>J.path===$))return;let Z={id:dz(),path:$,name:UF($),status:"pending"};this.snapshot.files.push(Z);try{this.save()}catch(J){throw Z.status="failed",Z.error=J instanceof Error?J.message:String(J),J}this.queue=this.queue.then(async()=>{try{if(this.abort.signal.throwIfAborted(),this.persistenceError)throw Error(this.persistenceError);let J=await this.getFolder(),Y=await this.deps.uploadFile($,J,(Q)=>{Z.file={...Q},Z.bytes=Q.bytes,this.save()},this.abort.signal);Z.file=Y,Z.bytes=Y.bytes,Z.status="ready",this.save()}catch(J){Z.status="failed",Z.error=`${Z.file?"文件已上传,后续处理失败:":""}${J instanceof Error?J.message:String(J)}`;try{this.save()}catch(Y){this.snapshot.error=Y instanceof Error?Y.message:String(Y)}if(!this.abort.signal.aborted)try{await this.deps.reportError(`❌ 文件交付失败:${Z.name}
233
+ `+iD($,G)+`
234
+ `)}function v6($){let Z=Uz.then($);return Uz=Z.then(()=>{},()=>{}),Z}async function w6($,Z){nD($,Z),rY(),ZJ(),await k4()}function Az($,Z){return v6(()=>w6($,Z))}function Oz($,Z,J,Y="default"){return v6(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=h.token_sources[$],z=Q.modelSelection.mode==="catalog",W=P0(X?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...W,Z])]:W.filter((_)=>_!==Z)).join(",")}:{models:H.join(",")};await w6($,G);let B=H0($,Y);if(B?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${B?.modelCatalogState?.error??"MISS"}`)})}function Rz($,Z,J="default"){return v6(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=h.token_sources[$];await w6($,{custom_models:[...P0(H?.custom_models),Y].join(",")});let X=H0($,J);if(X?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${X?.modelCatalogState?.error??"MISS"}`)})}function Nz($,Z,J="default"){return v6(async()=>{let Y=H0($,J),Q=Y?.modelSelection?.availableModels.find((W)=>W.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=h.token_sources[$]??{},H=(W)=>W?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),X={custom_models:P0(V.custom_models).filter((W)=>!H(W)).join(","),hidden_models:P0(V.hidden_models).filter((W)=>!H(W)).join(","),...V.models!==void 0?{models:P0(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 w6($,X);let z=H0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var Uz;var YJ=O(()=>{V0();k0();JJ();Y0();x0();u1();Uz=Promise.resolve()});var QJ={};N$(QJ,{runTokenSourceSetup:()=>oD,onTokenSourceEnable:()=>aD});async function aD($,Z){let J=P$(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 c($.chatId,K$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await E($.chatId,"请在运行 Lodestar 的本机执行 `claude auth login` 登录 Claude 订阅,完成后发送 `md` 刷新。");else if(J.kind==="claude-native")await E($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function oD($,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 Az(Y.configSectionId,Q.config);let V=P$(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 VJ=O(()=>{t();Y0();YJ();g2()});async function Tz($,Z,J="",Y){let Q=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Q){let{runCodexNamedHi:G}=await Promise.resolve().then(() => (S6(),uZ));return await G($,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:G}=await Promise.resolve().then(() => (S6(),uZ));return await G($,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;let X=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(X)return await $.runFileDeliveryCommand((X[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let z=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(z){let{runTokenSourceSetup:G}=await Promise.resolve().then(() => (VJ(),QJ));return await G($,z[1].trim().toLowerCase(),(z[2]??"").trim()),!0}let W=rD.get(Z.trim().toLowerCase());if(!W)return!1;switch(W){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(() => (g2(),$X));if(!await c($.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":{let G=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let _=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!_,onStatus:(j)=>$.setStatusCard(_,j)}),await $.closeStatusCard(_,"\uD83D\uDED1 已取消额度恢复")}catch(j){throw await $.closeStatusCard(_,`❌ ${N(j)}`),j}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(G)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await E($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let _=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(_)await $.closeStatusCard(_,"⚪ 无正在执行的 turn");else await E($.chatId,"⚪ 当前没有正在执行的 turn");return!0}K(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let B=new Set;for(let[_,j]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(j)b0(_,j);u0(_,"CrossMark"),B.add(_)}for(let _ of $.pendingMidTurnMsgs)if(_.msgId&&!B.has(_.msgId))u0(_.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} 未确认终止: ${N(D)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${B} 停止收尾失败: ${N(D)}`}finally{try{await $.closeStatusCard(j,P)}catch(D){K(`session "${$.sessionName}": kill status card close failed: ${N(D)}`),await v($.chatId,`${P}
235
+ ⚠️ kill 状态卡片终态写入失败: ${N(D)}`)}}if(q&&!j)await v($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let G=$.lastSessionId?O0($.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 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 rD;var Ez=O(()=>{t();f();rD=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 eD($){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 $F($,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 ZF($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=N8($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=T8($.contextWindow);return` · \uD83E\uDDE0 ${HV(Z,J)} (${E8(Z,J)})`}async function xz($){$.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?O0(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=eD(J),z=$F(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,tD),B=W.threadId?` thread=${O0(W.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${B}${ZF(G)}`))}catch(W){if(X.cancel(),W instanceof P1)await H($.withModel(`ⓘ ${W.message}`));else await H(`❌ 上下文压缩失败: ${N(W)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var tD=1500;var Sz=O(()=>{B0();t()});import{randomUUID as YF}from"node:crypto";function QF($){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 XJ($,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 Cz($){await k4();let Z=YF(),J=QF($);$.modelPanels.set(Z,{models:[]});let Y=await c($.chatId,G5({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}));if(!Y)$.modelPanels.delete(Z),await v($.chatId,"❌ 模型面板发送失败");else{let Q=$.modelPanels.get(Z);if(Q)Q.messageId=Y}}async function zJ($,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=XJ($,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}),f6($,V,Y,0)}async function f6($,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/HJ));if(!Number.isInteger(Y)||Y<0||Y>=V)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*HJ,(Y+1)*HJ),Q.page=Y,Q.totalPages=V,{ok:!0,message:"",card:K5({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 bz($,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:XJ($,Q,V),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),f6($,Z,J,0)}async function kz($,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=[...B$.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 Nz(J,Y,$.codexAccountId());else await Oz(J,Y,Q,$.codexAccountId());for(let z of B$.all)for(let[W,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||W!==Z))z.modelPanels.delete(W);return{...await zJ($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(X){return{ok:!1,message:`模型列表更新失败:${N(X)}`}}}async function yz($,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:_5($.sessionName,Q.display,V)}}async function vz($,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 G$(Y.cardMessageId),Z$(j,1),q=await A0(j,R.modelPanel,_,{notifyCardFailure:!1}),!q)throw Error("model panel replace rejected");if(P=await R0(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 R0(j,{config:{streaming_mode:!1}})}catch(D){K(`model-custom: streaming-off retry MISS (${D?.message??D})`)}if(q&&P)try{await J$(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}
236
+ 请重新发送 model 打开面板。`;if(!await v($.chatId,P))K(`model-custom: visible fallback send MISS (${j})`);return!1},z=(_)=>X(x2(!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(x2(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await Rz(V.id,Q,$.codexAccountId())}catch(_){return K(`model-custom: config/refresh MISS (${N(_)})`),await z(`配置写入或模型刷新失败:${N(_)}`),!0}K(`model-custom: ${V.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let _ of B$.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=XJ($,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(x2(!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?r8({sessionName:$.sessionName,provider:B.provider,model:B.model,effort:B.efforts[0].effort,scope:fz($,B.provider??"codex")}):x2(!0,Q,_.message),_.message),!0}return await X(o8({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:B}),`✅ 模型 ${Q} 已补录成功。`),!0}async function wz($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:a8($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:a8($.sessionName)}}function VF($,Z){return j$(Z?.provider)?Z.provider:V2($)}function fz($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${L$(Z)} 时使用。`}async function hz($,Z,J="",Y="",Q=null){let V=Z.trim();if(!V)return await E($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=VF(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 WJ($,V,X.efforts[0].effort,J,Y,H);return{ok:!0,message:"",card:B5({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function WJ($,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=j$(V)?V:W?.models.find((U)=>U.model===H)?.provider??V2(H);if(G==="dsh"){if(!K0(X))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!D0(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!o0(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:`${L$(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:`当前已是 ${L$(G)} · ${H} / ${B}`,card:n8({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 后再切换到 ${L$(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 ZQ($.proc.setModelSettings(S,B),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,B,_.sourceId);let U=fz($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${L$(G)} · ${H} / ${B}`,card:n8({sessionName:$.sessionName,provider:G,model:H,effort:B,scope:U})}}catch(U){let S=`模型切换失败: ${N(U)}`;return K(`session "${$.sessionName}": set model settings failed: ${N(U)}`),await E($.chatId,`❌ ${S}`),{ok:!1,message:S}}}var HJ=20;var Iz=O(()=>{B0();GJ();Y0();YJ();F1();B0();t0();v$();t();f()});import{createHash as XF}from"node:crypto";function zF($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function d1($="default"){return WF(b$().map((Z)=>Z.forAccount?.($)??Z))}function WF($){let Z=[],J=[];for(let Y of $)GF(Y,Z,J);return{catalogGeneration:XF("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function GF($,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(KF($,Q,Y))}function KF($,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:zF($.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:gz($.defaultModel)===gz(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function gz($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var h6=O(()=>{Y0()});import{randomUUID as BF}from"node:crypto";async function mz($,Z){if(!Z.trim()){await v($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}uz(),await F2();let J=`agents_${BF()}`;if(O9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await c($.chatId,cz(J)))await v($.chatId,"❌ agents 面板发送失败")}function pz($,Z,J){let Y=LF($,J),Q=Number(Z);if(!Number.isInteger(Q))return qF("无效页码");let V=jF(Y.codexAccountId);return Y.page=Math.max(0,Math.min(V-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:cz($)}}function cz($){let Z=O9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=d1(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/I6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*I6;return T5({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+I6),failures:J.sourceFailures})}function jF($){return Math.max(1,Math.ceil(d1($).identities.length/I6))}function LF($,Z){uz();let J=O9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function qF($){return{ok:!1,message:$,card:$1({title:"agents",message:$,ok:!1})}}function uz(){let $=Date.now()-_F;for(let[Z,J]of O9)if(J.createdAt<$)O9.delete(Z)}var I6=8,_F=1800000,O9;var lz=O(()=>{t0();t();h6();Y0();O9=new Map});var _J={};N$(_J,{withTasklistLifecycleLock:()=>c6,tasklistNameForProject:()=>p6,reconcileTasklistDeletions:()=>MF,isTasklistAlreadyDeletedError:()=>dz,getTasklistBinding:()=>h$,enableTasklist:()=>KJ,deleteTasklistRemoteIdempotently:()=>iz,deleteTasklist:()=>BJ});import{existsSync as DF,readFileSync as FF}from"node:fs";function p6($){return`${$}[lodestar]`}function h$($){let Z=f$.get($);return Z?o2(Z):null}async function c6($,Z){let J=g6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),V=J.catch(()=>{}).then(()=>Q);g6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Y(),g6.get($)===V)g6.delete($)}}function dz($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function iz($,Z=g5){try{return await Z($),"deleted"}catch(J){if(dz(J))return"already_deleted";throw J}}async function KJ($,Z){return await c6($,async()=>{let J=h$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=p6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await h5(Z),V=await I5(Y,Q),H={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Q,createdAt:V.createdAt};return m6($,H),o2(H)})}async function BJ($,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},m6($,J);return await nz($,Z)})}async function nz($,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,m6($,J);try{if(await iz(Z)==="already_deleted")K(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(f$);return Q.delete($),az(Q),f$.delete($),o2(J)}catch(Y){let Q=h$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),m6($,Q);throw Y}}async function MF(){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,()=>nz(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 UF(){if(!DF(S9))return;try{let $=JSON.parse(FF(S9,"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:AF(Y.deleting)};f$.set(Z,Q)}K(`tasklist: loaded ${f$.size} project bindings`)}catch($){K(`tasklist: load map failed: ${$}`)}}function AF($){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 m6($,Z){let J=new Map(f$);J.set($,o2(Z)),az(J),f$.set($,o2(Z))}function az($=f$){let Z={};for(let[J,Y]of $)Z[J]=o2(Y);s(S9,Z)}function o2($){return JSON.parse(JSON.stringify($))}var f$,g6;var jJ=O(()=>{V0();t();f();x0();f$=new Map,g6=new Map;UF()});function X1($,Z,J=!1){let Y=$.worktreeProjectName();return R5({projectName:Y,tasklistName:p6(Y),binding:h$(Y),notice:Z,confirmDelete:J})}async function oz($){if(!await c($.chatId,X1($)))await v($.chatId,"❌ task 面板发送失败")}async function rz($){let Z=$.worktreeProjectName();try{let J=h$(Z),Y=await KJ(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:X1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${N(J)}`;return K(`session "${$.sessionName}": tasklist enable failed: ${N(J)}`),{ok:!1,message:Y,card:X1($,{type:"error",content:`❌ ${Y}`})}}}function sz($,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 tz($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let V=`已删除 ${(await BJ(J,Y)).name}`;return{ok:!0,message:V,card:X1($,{type:"success",content:`✅ ${V}`})}}catch(Q){let V=`删除失败: ${N(Q)}`;return K(`session "${$.sessionName}": tasklist delete failed: ${N(Q)}`),{ok:!1,message:V,card:X1($,{type:"error",content:`❌ ${V}`})}}}var ez=O(()=>{t0();t();f();jJ()});import{open as RF}from"node:fs/promises";import{basename as NF}from"node:path";function LJ($){if(typeof $!=="string"||!$.trim())throw Error("云空间链接 MISS");let Z=new URL($);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("云空间链接无效");return Z.href}function I$($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class $W{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:$0,getToken:A$,retry:S1,wait:(Z)=>new Promise((J)=>setTimeout(J,Z)),intervalMs:250}){this.deps=$}request($,Z,J="GET",Y,Q){let V=this.queue.then(()=>this.deps.retry($,async()=>{Q?.throwIfAborted();let H=await this.deps.getToken(),X=Y?.(),z=X instanceof FormData,W=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(W>0)await this.deps.wait(W);Q?.throwIfAborted(),this.lastStartedAt=Date.now();let G=AbortSignal.timeout(xF),B=new AbortController,_=()=>B.abort(G.reason),j=()=>B.abort(Q.reason);G.addEventListener("abort",_,{once:!0}),Q?.addEventListener("abort",j,{once:!0});let q=B.signal;try{let P=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${H}`,...!z&&X!==void 0?{"Content-Type":"application/json"}:{}},...X!==void 0?{body:z?X:JSON.stringify(X)}:{},signal:q});return(await C2(P,$)).data}catch(P){if(q.aborted&&q.reason?.name==="TimeoutError")throw q.reason;throw P}finally{G.removeEventListener("abort",_),Q?.removeEventListener("abort",j)}}));return this.queue=V.then(()=>{},()=>{}),V}async createFolder($,Z){let J=await this.request("创建交付文件夹","/drive/v1/files/create_folder","POST",()=>({name:$,folder_token:""}),Z);return{token:I$(J?.token,"交付文件夹"),url:LJ(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return I$(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Y=I$(J?.token,"群文件夹");if(Y!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Y,url:LJ($.url),name:I$(J?.name,"群文件夹名称")}}async renameFolder($,Z,J){try{await this.request("同步群文件夹名称",`/drive/v1/files/${encodeURIComponent($.token)}?type=folder`,"PATCH",()=>({new_title:Z}),J)}catch(Q){if(Q instanceof U$&&Q.code===99991672)throw new U$("同步群文件夹名称需要应用身份权限 drive:file:upload(飞书错误码 99991672)",Q.status,Q.code);throw Q}let Y=await this.getFolder($,J);if(Y.name!==Z)throw Error("群文件夹名称更新未生效");return Y}async grantFolderAccess($,Z,J,Y){I$(Z,"交付群"),I$(J,"交付发起人");let Q=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let H of[{member_type:"openid",member_id:J,perm:"full_access",type:"user"},{member_type:"openchat",member_id:Z,perm:"view",type:"chat"}])await this.request("设置交付文件夹权限",Q,"POST",()=>H,Y);let V=await this.request("核对交付文件夹权限",Q,"GET",void 0,Y);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[H,X,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((G)=>G.member_type===H&&G.member_id===X)?.perm!==z)throw Error(`交付文件夹权限未生效:${H} / ${z}`)}async closeFileLinkSharing($,Z){I$($,"交付文件");let J=`/drive/v2/permissions/${encodeURIComponent($)}/public?type=file`;if(await this.request("关闭交付文件链接分享",J,"PATCH",()=>({link_share_entity:"closed"}),Z),(await this.request("核对交付文件链接分享",J,"GET",void 0,Z))?.permission_public?.link_share_entity!=="closed")throw Error("交付文件链接分享未关闭,不能发布交付链接")}async uploadFile($,Z,J,Y){Y?.throwIfAborted();let Q=await RF($,"r");try{let V=await Q.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let H=NF($),X={file_name:H,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=TF){let q=await Q.readFile(),P=await Q.stat();if(q.length!==V.size||P.mtimeMs!==V.mtimeMs||P.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let D=new FormData;for(let[T,M]of Object.entries(X))D.append(T,String(M));return D.append("file",new Blob([Uint8Array.from(q)]),H),D},Y)}else{let q=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>X,Y),P=I$(q?.upload_id,"分片上传事务"),D=q?.block_size,T=q?.block_num;if(!Number.isSafeInteger(D)||D<=0||D>EF||!Number.isSafeInteger(T)||T!==Math.ceil(V.size/D))throw Error("云空间返回的分片策略无效");for(let A=0;A<T;A++){Y?.throwIfAborted();let U=Math.min(D,V.size-A*D),S=Buffer.alloc(U),C=0;while(C<U){let w=await Q.read(S,C,U-C,A*D+C);if(!w.bytesRead)throw Error("交付文件在分片读取时发生变化");C+=w.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let w=new FormData;return w.append("upload_id",P),w.append("seq",String(A)),w.append("size",String(U)),w.append("file",new Blob([Uint8Array.from(S)]),H),w},Y)}let M=await Q.stat();if(M.size!==V.size||M.mtimeMs!==V.mtimeMs||M.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:P,block_num:T}),Y)}let W=I$(z?.file_token,"已上传文件"),G={token:W,url:"",name:H,bytes:V.size};J(G),await this.closeFileLinkSharing(W,Y);let B=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:W,doc_type:"file"}],with_url:!0}),Y),_=B?.metas?.find((q)=>q.doc_token===W&&q.doc_type==="file");if(B?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let j={...G,url:LJ(_.url)};return J(j),j}finally{await Q.close()}}}var TF=20971520,EF=20971520,xF=60000,i1;var ZW=O(()=>{f0();t();J6();i1=new $W});import{randomUUID as JW}from"node:crypto";import{basename as SF}from"node:path";class qJ{deps;snapshot;queue=Promise.resolve();folderPromise;finishPromise;persistenceError;abort=new AbortController;constructor($,Z){this.deps=Z;if(!$.chatId.trim()||!$.managerOpenId.trim())throw Error("无法确认交付群或本次交付发起人");this.snapshot={...$,version:1,id:JW(),folderAccessReady:!1,files:[]}}add($){if(this.finishPromise)throw Error("本次文件交付已结束");if(this.abort.signal.throwIfAborted(),this.snapshot.files.some((J)=>J.path===$))return;let Z={id:JW(),path:$,name:SF($),status:"pending"};this.snapshot.files.push(Z);try{this.save()}catch(J){throw Z.status="failed",Z.error=J instanceof Error?J.message:String(J),J}this.queue=this.queue.then(async()=>{try{if(this.abort.signal.throwIfAborted(),this.persistenceError)throw Error(this.persistenceError);let J=await this.getFolder(),Y=await this.deps.uploadFile($,J,(Q)=>{Z.file={...Q},Z.bytes=Q.bytes,this.save()},this.abort.signal);Z.file=Y,Z.bytes=Y.bytes,Z.status="ready",this.save()}catch(J){Z.status="failed",Z.error=`${Z.file?"文件已上传,后续处理失败:":""}${J instanceof Error?J.message:String(J)}`;try{this.save()}catch(Y){this.snapshot.error=Y instanceof Error?Y.message:String(Y)}if(!this.abort.signal.aborted)try{await this.deps.reportError(`❌ 文件交付失败:${Z.name}
236
237
  ${Z.error}`)}catch(Y){this.snapshot.error=`错误提示发送失败:${String(Y)}`}}})}finish(){return this.finishPromise??=this.publish(),this.finishPromise}cancel($){if(this.abort.signal.aborted||!this.snapshot.files.some((Z)=>Z.status==="pending"))return!1;return this.snapshot.error=`未完成的文件上传已取消:${$}`,this.abort.abort(new DOMException($,"AbortError")),!0}save(){try{this.deps.persist(this.snapshot)}catch($){throw this.persistenceError=`保存文件交付记录失败:${$ instanceof Error?$.message:String($)}`,Error(this.persistenceError)}}getFolder(){return this.folderPromise??=(async()=>{let $=await this.deps.resolveFolder(this.snapshot,this.abort.signal);return this.snapshot.folder=$,this.snapshot.folderAccessReady=!0,this.save(),$})(),this.folderPromise}async publish(){if(await this.queue,!this.snapshot.files.length)return[];this.snapshot.completedAt=Date.now();try{this.save()}catch(Z){this.snapshot.error=Z instanceof Error?Z.message:String(Z)}let $;try{if($=await this.deps.sendCard(this.snapshot),!$)throw Error("飞书未返回交付卡消息 ID")}catch(Z){let J=`交付卡发送失败:${Z instanceof Error?Z.message:String(Z)}`;this.snapshot.error=J;try{this.save()}catch(Y){this.snapshot.error+=`;${String(Y)}`}return await this.deps.reportError(`❌ ${this.snapshot.error}${this.snapshot.folderAccessReady?`
237
- 已上传文件所在文件夹:${this.snapshot.folder.url}`:""}`),[]}this.snapshot.messageId=$;try{this.save()}catch(Z){await this.deps.reportError(`❌ 交付卡已发送,但${String(Z)}`)}return this.snapshot.files.filter((Z)=>Z.status==="ready").map((Z)=>Z.path)}}var iz=()=>{};class BJ{deps;groups;locks=new Map;constructor($){this.deps=$}get($){return structuredClone(this.load().get($)??{enabled:!1})}mode($){return this.get($).enabled?"drive":"chat"}enable($,Z){return this.exclusive($,async()=>{let J=await this.prepare($,Z,!0);return this.commit($,{enabled:!0,folder:J}),this.get($)})}disable($){return this.exclusive($,async()=>{return this.commit($,{...this.get($),enabled:!1}),this.get($)})}resolveFolder($,Z){return this.exclusive($.chatId,()=>this.prepare($.chatId,$.managerOpenId,!1,Z))}bindExisting($,Z,J){return this.exclusive($,async()=>{let Y=this.get($);if(Y.folder&&Y.folder.token!==J.token)throw Error("本群已经绑定其他文件夹");let Q=await this.deps.getFolder(J);return this.commit($,{...Y,folder:Q}),await this.prepare($,Z,!1),this.get($)})}async prepare($,Z,J,Y){if(Y?.throwIfAborted(),!$.trim()||!Z.trim())throw Error("无法确认交付群或管理权限接收人");let Q=await this.deps.getChatName($,Y);if(!Q.trim())throw Error("群名称 MISS");let V=this.get($),H;if(!V.folder){if(!J)throw Error("本群尚未绑定云空间文件夹,请先发送 files on");H={...await this.deps.createFolder(Q,Y),name:Q},this.commit($,{...V,folder:H})}else H=V.folder;let X=await this.deps.getFolder(H,Y);if(X.token!==H.token)throw Error("云空间返回的文件夹与本群绑定不一致");if(H=X.name===Q?X:await this.deps.renameFolder(X,Q,Y),H.name!==Q)throw Error("文件夹名称尚未与群名同步");return this.commit($,{...this.get($),folder:H}),await this.deps.grantFolderAccess(H,$,Z,Y),H}exclusive($,Z){let Y=(this.locks.get($)??Promise.resolve()).then(Z),Q=Y.then(()=>{},()=>{});return this.locks.set($,Q),Q.then(()=>{if(this.locks.get($)===Q)this.locks.delete($)}),Y}load(){if(this.groups)return this.groups;let $=this.deps.read();if($===void 0)return this.groups=new Map,this.groups;let Z=JSON.parse($);if(Z?.version!==1||!Z.groups||typeof Z.groups!=="object"||Array.isArray(Z.groups))throw Error("群文件交付设置格式无效");let J=new Map;for(let[Y,Q]of Object.entries(Z.groups)){let V=Q;if(!Y||!V||typeof V.enabled!=="boolean")throw Error("群文件交付开关无效");if(V.enabled&&!V.folder)throw Error("已启用的群缺少文件夹绑定");if(V.folder){if(typeof V.folder.token!=="string"||!V.folder.token.trim()||typeof V.folder.name!=="string"||!V.folder.name.trim()||typeof V.folder.url!=="string")throw Error("群文件夹绑定无效");let H=new URL(V.folder.url);if(H.protocol!=="https:"||H.username||H.password)throw Error("群文件夹链接无效")}J.set(Y,structuredClone(V))}return this.groups=J,J}commit($,Z){let J=new Map(this.load());J.set($,structuredClone(Z)),this.deps.write({version:1,groups:Object.fromEntries(J)}),this.groups=J}}import{join as MF}from"node:path";import{readFileSync as AF}from"node:fs";function nz($){return new KJ($,{resolveFolder:(Z,J)=>s2.resolveFolder(Z,J),uploadFile:(Z,J,Y,Q)=>o1.uploadFile(Z,J,Y,Q),sendCard:(Z)=>c($.chatId,A5(Z)),persist:(Z)=>s(MF(rJ,`${Z.id}.json`),Z),reportError:async(Z)=>{if(K(`file delivery ${$.projectName}: ${Z}`),!await E($.chatId,Z))throw Error(Z)}})}var s2;var az=O(()=>{t();lz();iz();u8();V0();S0();f();s2=new BJ({read:()=>{try{return AF(j7,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>s(j7,$),getChatName:($,Z)=>o1.getChatName($,Z),createFolder:($,Z)=>o1.createFolder($,Z),getFolder:($,Z)=>o1.getFolder($,Z),renameFolder:($,Z,J)=>o1.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Y)=>o1.grantFolderAccess($,Z,J,Y)})});async function oz($,Z,J,Y,Q){let V,H="",X="";try{switch(V=Q.get($),Y.trim().toLowerCase()){case"":case"status":break;case"on":V=await Q.enable($,J),H="已开启本群云空间交付;之后新开始的交付使用此模式。";break;case"off":V=await Q.disable($),H="已恢复直接发送聊天附件;云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(W){X=W instanceof Error?W.message:String(W);try{V=Q.get($)}catch{V=void 0}}let z=O5({groupName:Z,settings:V,notice:H,error:X});if(!await Q.sendCard(z))await Q.reportError(`❌ 文件交付设置卡发送失败${X?`:${X}`:""}`)}var rz=O(()=>{u8()});function tz($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
238
- `)}function ez($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",tz(Z),"- 文件交付约定由 Lodestar 按群设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写群配置。"}`,J[$],...OF].join(`
239
- `)}function $W($){return`[Lodestar 文件交付约定更新]
238
+ 已上传文件所在文件夹:${this.snapshot.folder.url}`:""}`),[]}this.snapshot.messageId=$;try{this.save()}catch(Z){await this.deps.reportError(`❌ 交付卡已发送,但${String(Z)}`)}return this.snapshot.files.filter((Z)=>Z.status==="ready").map((Z)=>Z.path)}}var YW=()=>{};class PJ{deps;groups;locks=new Map;constructor($){this.deps=$}get($){return structuredClone(this.load().get($)??{enabled:!1})}mode($){return this.get($).enabled?"drive":"chat"}enable($,Z){return this.exclusive($,async()=>{let J=await this.prepare($,Z,!0);return this.commit($,{enabled:!0,folder:J}),this.get($)})}disable($){return this.exclusive($,async()=>{return this.commit($,{...this.get($),enabled:!1}),this.get($)})}resolveFolder($,Z){return this.exclusive($.chatId,()=>this.prepare($.chatId,$.managerOpenId,!1,Z))}bindExisting($,Z,J){return this.exclusive($,async()=>{let Y=this.get($);if(Y.folder&&Y.folder.token!==J.token)throw Error("本群已经绑定其他文件夹");let Q=await this.deps.getFolder(J);return this.commit($,{...Y,folder:Q}),await this.prepare($,Z,!1),this.get($)})}async prepare($,Z,J,Y){if(Y?.throwIfAborted(),!$.trim()||!Z.trim())throw Error("无法确认交付群或管理权限接收人");let Q=await this.deps.getChatName($,Y);if(!Q.trim())throw Error("群名称 MISS");let V=this.get($),H;if(!V.folder){if(!J)throw Error("本群尚未绑定云空间文件夹,请先发送 files on");H={...await this.deps.createFolder(Q,Y),name:Q},this.commit($,{...V,folder:H})}else H=V.folder;let X=await this.deps.getFolder(H,Y);if(X.token!==H.token)throw Error("云空间返回的文件夹与本群绑定不一致");if(H=X.name===Q?X:await this.deps.renameFolder(X,Q,Y),H.name!==Q)throw Error("文件夹名称尚未与群名同步");return this.commit($,{...this.get($),folder:H}),await this.deps.grantFolderAccess(H,$,Z,Y),H}exclusive($,Z){let Y=(this.locks.get($)??Promise.resolve()).then(Z),Q=Y.then(()=>{},()=>{});return this.locks.set($,Q),Q.then(()=>{if(this.locks.get($)===Q)this.locks.delete($)}),Y}load(){if(this.groups)return this.groups;let $=this.deps.read();if($===void 0)return this.groups=new Map,this.groups;let Z=JSON.parse($);if(Z?.version!==1||!Z.groups||typeof Z.groups!=="object"||Array.isArray(Z.groups))throw Error("群文件交付设置格式无效");let J=new Map;for(let[Y,Q]of Object.entries(Z.groups)){let V=Q;if(!Y||!V||typeof V.enabled!=="boolean")throw Error("群文件交付开关无效");if(V.enabled&&!V.folder)throw Error("已启用的群缺少文件夹绑定");if(V.folder){if(typeof V.folder.token!=="string"||!V.folder.token.trim()||typeof V.folder.name!=="string"||!V.folder.name.trim()||typeof V.folder.url!=="string")throw Error("群文件夹绑定无效");let H=new URL(V.folder.url);if(H.protocol!=="https:"||H.username||H.password)throw Error("群文件夹链接无效")}J.set(Y,structuredClone(V))}return this.groups=J,J}commit($,Z){let J=new Map(this.load());J.set($,structuredClone(Z)),this.deps.write({version:1,groups:Object.fromEntries(J)}),this.groups=J}}import{join as CF}from"node:path";import{readFileSync as bF}from"node:fs";function QW($){return new qJ($,{resolveFolder:(Z,J)=>r2.resolveFolder(Z,J),uploadFile:(Z,J,Y,Q)=>i1.uploadFile(Z,J,Y,Q),sendCard:(Z)=>c($.chatId,I3(Z)),persist:(Z)=>s(CF($Y,`${Z.id}.json`),Z),reportError:async(Z)=>{if(K(`file delivery ${$.projectName}: ${Z}`),!await E($.chatId,Z))throw Error(Z)}})}var r2;var VW=O(()=>{t();ZW();YW();R8();V0();x0();f();r2=new PJ({read:()=>{try{return bF(P7,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>s(P7,$),getChatName:($,Z)=>i1.getChatName($,Z),createFolder:($,Z)=>i1.createFolder($,Z),getFolder:($,Z)=>i1.getFolder($,Z),renameFolder:($,Z,J)=>i1.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Y)=>i1.grantFolderAccess($,Z,J,Y)})});async function HW($,Z,J,Y,Q){let V,H="",X="";try{switch(V=Q.get($),Y.trim().toLowerCase()){case"":case"status":break;case"on":V=await Q.enable($,J),H="已开启本群云空间交付;之后新开始的交付使用此模式。";break;case"off":V=await Q.disable($),H="已恢复直接发送聊天附件;云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(W){X=W instanceof Error?W.message:String(W);try{V=Q.get($)}catch{V=void 0}}let z=g3({groupName:Z,settings:V,notice:H,error:X});if(!await Q.sendCard(z))await Q.reportError(`❌ 文件交付设置卡发送失败${X?`:${X}`:""}`)}var XW=O(()=>{R8()});function WW($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
239
+ `)}function GW($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",WW(Z),"- 文件交付约定由 Lodestar 按群设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写群配置。"}`,J[$],...kF].join(`
240
+ `)}function KW($){return`[Lodestar 文件交付约定更新]
240
241
  以下约定从本轮起完整替换此前的文件交付约定:
241
- ${tz($)}`}function ZW(){return["---","name: lodestar-files",`description: ${JSON.stringify("在 Lodestar 飞书会话中交付本地生成或已有的报告、PDF、视频等任务文件。主 Agent 用交付标记交给宿主发送,委派 Agent 返回文件路径;不用于搜索或编辑用户指定的已有云文档。")}`,"---","","# Lodestar 文件交付","","仅用于 Lodestar 托管的会话。交付标记需要宿主处理,不能在普通终端或其他聊天环境里把它当作上传命令。","","生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。","","交付前完成文件生成与必要检查,确认文件存在、可读取。多个文件各写一行交付标记;把下面的示例路径替换成真实文件路径,不要在说明中原样发送示例标记。","标记写在主 Agent 的回复正文里,不写进脚本的标准输出、文件内容或仅放在工具返回值里。","","```text","[[send: /abs/path/report.pdf]]","[[send: /abs/path/video.mp4]]","```","","交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。","","## 交付要求","","以 Lodestar 启动 Agent 时注入的文件交付约定及后续约定更新为准。只有约定明确给出文件大小上限时,才按该上限检查和处理;不自行查询配置、推断限制或按账号认证状态决定交付方式。","","`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写群配置。","","## 宿主负责的结果","","云空间模式下,Lodestar 把本群各轮文件放进与群名一致的固定文件夹。独立卡片只列本轮文件,“管理群文件”打开本群所有历史云空间交付文件。目录复用、上传与重试、授权和发卡都由后台实现;这里不需要上传脚本或接口步骤。","","交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。","","系统报告交付失败时,向用户说明实际错误;不要换上传工具、身份或存储来源掩盖失败。用户另行要求管理已有云文档时,按该请求的实际范围处理,不把它混入本地产物交付。","","图像生成工具的图片沿用 Lodestar 自动展示规则,不再重复提交交付标记。",""].join(`
242
- `)}var sz="lodestar-files",OF;var c6=O(()=>{OF=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});import{execFileSync as RF}from"node:child_process";import{existsSync as r1,readdirSync as NF,readFileSync as TF,realpathSync as _J,statSync as EF}from"node:fs";import{dirname as xF,join as YW,resolve as l6}from"node:path";async function d6($,Z){let J=_J($),Y=process.platform==="win32"?J.toLowerCase():J,Q=u6.get(Y)??Promise.resolve(),V,H=new Promise((z)=>{V=z}),X=Q.catch(()=>{}).then(()=>H);u6.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(V(),u6.get(Y)===X)u6.delete(Y)}}function s1($){let Z=$.trim();if(!SF.test(Z))return null;return Z}function QW($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function e2($,Z){return`${$}[${Z}]`}function VW($){return`${t2}${$}`}function $4($,Z,J){return YW(xF($),e2(Z,J))}function HW($,Z,J){let Y=bF($,Z,J);if(!Y)return null;let Q=TF(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function XW($,Z){LJ($);let J=E0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${t2}`]).split(`
243
- `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(t2)),Y=qJ($),Q=[];for(let V of J){let H=V.slice(t2.length);if(!s1(H))continue;let X=e2(Z,H),z=$4($,Z,H),W=Y.get(V)??null,G=!!W&&r1(W),B=KW($,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&&r1(W))try{let q=E0(W,["status","--porcelain=v1","--branch"]).split(`
244
- `).filter(Boolean);_.statusLine=q[0]?.startsWith("## ")?q[0].slice(3):null,_.dirtyCount=q.filter((P)=>!P.startsWith("## ")).length}catch(j){_.error=PJ(j)}Q.push(_)}return Q.sort((V,H)=>V.slug.localeCompare(H.slug))}function zW($,Z,J){let Y=s1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);LJ($);let Q=VW(Y),V=e2(Z,Y),H=$4($,Z,Y),X=wF($,Q),z=qJ($).get(Q)??null,W=X&&!z&&KW($,Q,!1)==="merged"?E0($,["rev-parse","HEAD"]).trim():null;if(z){if(l6(z)!==l6(H))throw Error(`branch ${Q} is already mounted at ${z}`);return GW(H,Q),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(r1(H)){if(!EF(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(E0($,["worktree","add",H,Q]),W)E0(H,["rebase",W]);return{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return E0($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function WW($,Z,J){let Y=jJ($,Z,J);if(!r1(Y.worktreePath))return Y;return E0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function jJ($,Z,J){let Y=s1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);LJ($);let Q=VW(Y),V=e2(Z,Y),H=$4($,Z,Y),z=qJ($).get(Q)??null??H;if(!r1(z))return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1};GW(z,Q);let W=E0(z,["status","--porcelain=v1"]).split(`
242
+ ${WW($)}`}function BW(){return["---","name: lodestar-files",`description: ${JSON.stringify("在 Lodestar 飞书会话中交付本地生成或已有的报告、PDF、视频等任务文件。主 Agent 用交付标记交给宿主发送,委派 Agent 返回文件路径;不用于搜索或编辑用户指定的已有云文档。")}`,"---","","# Lodestar 文件交付","","仅用于 Lodestar 托管的会话。交付标记需要宿主处理,不能在普通终端或其他聊天环境里把它当作上传命令。","","生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。","","交付前完成文件生成与必要检查,确认文件存在、可读取。多个文件各写一行交付标记;把下面的示例路径替换成真实文件路径,不要在说明中原样发送示例标记。","标记写在主 Agent 的回复正文里,不写进脚本的标准输出、文件内容或仅放在工具返回值里。","","```text","[[send: /abs/path/report.pdf]]","[[send: /abs/path/video.mp4]]","```","","交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。","","## 交付要求","","以 Lodestar 启动 Agent 时注入的文件交付约定及后续约定更新为准。只有约定明确给出文件大小上限时,才按该上限检查和处理;不自行查询配置、推断限制或按账号认证状态决定交付方式。","","`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写群配置。","","## 宿主负责的结果","","云空间模式下,Lodestar 把本群各轮文件放进与群名一致的固定文件夹。独立卡片只列本轮文件,“管理群文件”打开本群所有历史云空间交付文件。目录复用、上传与重试、授权和发卡都由后台实现;这里不需要上传脚本或接口步骤。","","交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。","","系统报告交付失败时,向用户说明实际错误;不要换上传工具、身份或存储来源掩盖失败。用户另行要求管理已有云文档时,按该请求的实际范围处理,不把它混入本地产物交付。","","图像生成工具的图片沿用 Lodestar 自动展示规则,不再重复提交交付标记。",""].join(`
243
+ `)}var zW="lodestar-files",kF;var u6=O(()=>{kF=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});import{execFileSync as yF}from"node:child_process";import{existsSync as n1,readdirSync as vF,readFileSync as wF,realpathSync as DJ,statSync as fF}from"node:fs";import{dirname as hF,join as jW,resolve as d6}from"node:path";async function i6($,Z){let J=DJ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=l6.get(Y)??Promise.resolve(),V,H=new Promise((z)=>{V=z}),X=Q.catch(()=>{}).then(()=>H);l6.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(V(),l6.get(Y)===X)l6.delete(Y)}}function a1($){let Z=$.trim();if(!IF.test(Z))return null;return Z}function LW($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function t2($,Z){return`${$}[${Z}]`}function qW($){return`${s2}${$}`}function e2($,Z,J){return jW(hF($),t2(Z,J))}function PW($,Z,J){let Y=gF($,Z,J);if(!Y)return null;let Q=wF(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function DW($,Z){MJ($);let J=T0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${s2}`]).split(`
244
+ `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(s2)),Y=UJ($),Q=[];for(let V of J){let H=V.slice(s2.length);if(!a1(H))continue;let X=t2(Z,H),z=e2($,Z,H),W=Y.get(V)??null,G=!!W&&n1(W),B=AW($,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&&n1(W))try{let q=T0(W,["status","--porcelain=v1","--branch"]).split(`
245
+ `).filter(Boolean);_.statusLine=q[0]?.startsWith("## ")?q[0].slice(3):null,_.dirtyCount=q.filter((P)=>!P.startsWith("## ")).length}catch(j){_.error=AJ(j)}Q.push(_)}return Q.sort((V,H)=>V.slug.localeCompare(H.slug))}function FW($,Z,J){let Y=a1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);MJ($);let Q=qW(Y),V=t2(Z,Y),H=e2($,Z,Y),X=uF($,Q),z=UJ($).get(Q)??null,W=X&&!z&&AW($,Q,!1)==="merged"?T0($,["rev-parse","HEAD"]).trim():null;if(z){if(d6(z)!==d6(H))throw Error(`branch ${Q} is already mounted at ${z}`);return UW(H,Q),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(n1(H)){if(!fF(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(T0($,["worktree","add",H,Q]),W)T0(H,["rebase",W]);return{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return T0($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:V,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function MW($,Z,J){let Y=FJ($,Z,J);if(!n1(Y.worktreePath))return Y;return T0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function FJ($,Z,J){let Y=a1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);MJ($);let Q=qW(Y),V=t2(Z,Y),H=e2($,Z,Y),z=UJ($).get(Q)??null??H;if(!n1(z))return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1};UW(z,Q);let W=T0(z,["status","--porcelain=v1"]).split(`
245
246
  `).filter(Boolean);if(W.length>0){let G=W.slice(0,8).join(`
246
247
  `);throw Error(`worktree has uncommitted changes:
247
- ${G}`)}return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1}}function LJ($){if(!r1($))throw Error(`project directory does not exist: ${$}`);let Z=E0($,["rev-parse","--show-toplevel"]).trim();if(_J(Z)!==_J($))throw Error(`${$} is not the git repository root (${Z})`)}function GW($,Z){let J=E0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function bF($,Z,J){let Y=CF($);if(!Y?.startsWith(t2))return null;let Q=Y.slice(t2.length);if(!s1(Q))throw Error(`invalid worktree branch "${Y}"`);let V=$4(Z,J,Q);if(l6($)!==l6(V))return null;let H=yF($,kF(Q));return H?{path:H,slug:Q}:null}function CF($){if(!r1($))return null;try{return E0($,["branch","--show-current"]).trim()||null}catch(Z){if(vF(Z))return null;throw Z}}function kF($){return $.split("-",1)[0]??$}function yF($,Z){let J=`agents.${Z}.md`,Y=NF($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?YW($,Y[0]):null}function wF($,Z){try{return E0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function KW($,Z,J){let Y=E0($,["rev-parse",Z]).trim(),Q=E0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(JW($,Z,"HEAD"))return"merged";if(JW($,"HEAD",Z))return"active";return"stale"}function JW($,Z,J){try{return E0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function qJ($){let Z=new Map,J=E0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
248
- `)){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 E0($,Z){try{return RF("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(PJ(J))}}function PJ($){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 vF($){return/not a git repository/i.test(PJ($))}var t2="work/",SF,u6;var BW=O(()=>{SF=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,u6=new Map});function B1($){return QW(M$($.sessionName)??$.sessionName)}function Z4($){return w8(B1($))}function jW($){let Z=M$($.sessionName)??$.sessionName,J=B1($),Y=w8(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return $4(Y,J,Q)}function LW($,Z,J=$.currentProvider()){let Y=ez(J,Z),Q=T9($);return Q?`${Y}
249
- ${Q}`:Y}function qW($,Z){return T9($)??""}function DJ($){return T9($)?"已载入wt特殊约定":null}function PW($,Z){let J=DJ($);return J?`${Z}
250
- ${J}`:Z}function T9($){let Z=B1($),J=HW($.workDir,Z4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
251
- `)}async function DW($,Z,J){if(!Z){await FJ($);return}let Y=s1(Z);if(!Y){await E($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await E($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=B1($),V=Z4($);try{await d6(V,async()=>{let H;try{H=zW(V,Q,Y)}catch(X){await E($.chatId,`❌ wt 失败: ${R(X)}`);return}try{let X=await K5(H.chatName,J),z=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await c($.chatId,_9({slug:Y,branch:H.branch,status:z})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await c(X.chatId,_9({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await w(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await E($.chatId,`❌ wt 已建,拉群失败: ${R(X)}`)}})}catch(H){await E($.chatId,`❌ wt 失败: ${R(H)}`)}}async function FW($,Z){let J=B1($),Y=Z4($);return await d6(Y,async()=>{return await hF(J,Y,Z)})}async function hF($,Z,J){let Y=XW(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,V=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await f8();return e5({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:V.map((X)=>{let z=H.get(X.chatName)??[],W=q0.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 FJ($){try{let Z=await FW($);if(!await c($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await E($.chatId,`❌ wt 列表失败: ${R(Z)}`)}}async function _W($,Z,J,Y){try{return{ok:Z,message:J,card:await FW($,{type:Y,content:J})}}catch(Q){let V=`列表刷新失败: ${R(Q)}`;return K(`session "${$.sessionName}": wt action panel refresh failed: ${R(Q)}`),{ok:!1,message:`${J}
252
- ${V}`,card:_9({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function UW($,Z){let J=s1(Z);if(!J)return _W($,!1,"❌ 名称无效","error");let Y=B1($),Q=Z4($),V;try{V=await d6(Q,async()=>{let H=e2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};jJ(Q,Y,J);let X=await _5(H),z=WW(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",z.branch].join(`
253
- `),type:"success"}})}catch(H){V={ok:!1,message:`❌ 解散 ${J} 失败: ${R(H)}`,type:"error"}}return _W($,V.ok,V.message,V.type)}var MW=O(()=>{c6();Q$();t();f();BW()});import{closeSync as gF,openSync as mF,readSync as pF,readdirSync as cF,statSync as uF}from"node:fs";import{randomUUID as MJ}from"node:crypto";import{join as lF}from"node:path";function n6($){return M$($.sessionName)??$.sessionName}function OW($){let Z=Q5($,UJ);return UJ.add(Z),Z}function RW($){UJ.delete($)}function J4($){let Z=AW.get($);if(!Z)Z=new Map,AW.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let V=Q.status==="consumed"?nF:iF,H=Q.consumedAt??Q.createdAt;if(J-H>V)Z.delete(Y)}return Z}function oF($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function NW($,Z,J,Y){let Q={id:MJ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:n6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return J4($).set(Q.id,Q),Q}function AJ($,Z,J,Y,Q){let V=J4($).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||!oF(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 i6($){$.status="consumed",$.consumedAt=Date.now()}function rF($){return{kind:"fork",source:$.source,through:$}}function sF($){return d4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function tF($){let Z=i4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return j0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function eF($){let Z=_8($),J;try{J=cF(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(X2("claude",V))continue;let H=lF(Z,Q),X;try{X=uF(H).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:V,cwd:$,preview:ZU(H),ts:X})}return Y.sort((Q,V)=>V.ts-Q.ts)}function $U($){let Z=$.slice().sort((Q,V)=>V.ts-Q.ts),J=Date.now()-dF,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(aF,Math.max(10,Y)))}function ZU($){let Z="",J=null;try{J=mF($,"r");let Q=Buffer.alloc(65536),V=pF(J,Q,0,65536,0);Z=Q.subarray(0,V).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)gF(J)}let Y="";for(let Q of Z.split(`
254
- `)){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=JU(H.message);if(X)Y=X}}return Y.slice(0,80)}function JU($){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 TW($,Z,J){if(!J){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=sF($),Q=tF($),V=new Map,H=[];for(let G=0;G<Y.length;G++){let B=Y[G];if(G===0&&Q===null)continue;let _=MJ(),j=G===0?Q:rF(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=NW($,Z,J,V),z=ZZ({projectName:n6($),panelId:X.id,mode:Z,entries:H}),W;try{W=await c($.chatId,z)}catch(G){throw J4($).delete(X.id),G}if(!W)J4($).delete(X.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function EW($,Z){return TW($,"fork",Z)}function xW($,Z){return TW($,"back",Z)}async function SW($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():eF($.workDir)}catch(z){await w($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=$U(J).map((z)=>{let W=MJ();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=NW($,"resume",Z,Y),H=JZ({projectName:n6($),panelId:V.id,entries:Q}),X;try{X=await c($.chatId,H)}catch(z){throw J4($).delete(V.id),z}if(!X)J4($).delete(V.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function bW($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await E($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=OW(n6($));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{RW(J)}if(!Y.ok){await E($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await E($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function CW($){if(!M$($.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 kW($,Z,J,Y){let Q=AJ($,"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=OW(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{RW(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{i6(V)}}async function yW($,Z,J,Y){let Q=AJ($,"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 c($.chatId,YZ({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?` ${R0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{i6(V)}}async function wW($,Z,J,Y){let Q=AJ($,"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 i6(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{i6(V)}}var dF=86400000,iF=1800000,nF=3600000,aF=40,AW,UJ;var vW=O(()=>{t();Q$();f();S4();q4();A1();AW=new WeakMap,UJ=new Set});import{existsSync as fW}from"node:fs";import{randomBytes as QU,timingSafeEqual as VU}from"node:crypto";import{isAbsolute as HU}from"node:path";function RJ($,Z=new Set){if($ instanceof _2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=RJ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return RJ($.cause,Z);return null}function XU($){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 zU($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function WU($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function t1(){return h.runtime?.live_elapsed??"bucket"}function mW($,Z){return`${$} (${t$(Date.now()-Z,t1()).label})`}var IW="Thinking...",GU="Writing...",KU="Working...",OJ=1e4,a6=720000,BU=50,_U=256,o6=1e4,gW=250,K$;var VJ=O(()=>{q4();D4();_0();O1();j3();_0();y0();w3();Y0();p0();E2();S4();v$();Q$();t();f();V0();d5();w$();P9();FZ();VX();DX();yX();N6();fX();qz();Dz();Ez();yz();cz();az();rz();c6();MW();vW();A1();K$=class K${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;procFileDeliveryModes=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;fileDeliveries=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;K$.all.add(this);let Y=X5($);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=Z1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)K(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=n4($);if(V)if(this.selectedProvider!=="claude")$$($,[],null,null),K(`session "${$}": cleared pending Claude fork after provider changed`);else{j0(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(r0(this.proc)).name}:{}}}get workDir(){return jW(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 D8(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?r0(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()===u?{}:{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)$$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=Z1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,b1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??u;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 z2({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!X2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!s4(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 j2({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: ${R(V)}; ${R(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=j8(this.workDir,$.sessionId);if(!fW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${R0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!s4(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Y=J?.enabled?J:void 0,Q=new j2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(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=${R(V)}; cleanup=${R(H)}`);if(V)throw V;if(H)throw H}return j0({kind:"resume",source:Z},this.selectedProvider,this.workDir),l4(this.sessionName,Z),Z}hasRunningPeerSession($){return[...K$.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 s0(this.selectedEffort)?this.selectedEffort:R4}return R4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&U0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=L$($,this.selectedModel??$.defaultModel);if(!U0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return a$}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"?a$:R4)}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"?a$:R4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return J0($,N.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:N.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return N5($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return j$($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(j0($.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=QU(32).toString("base64url");let Z={LODESTAR_AGENT_URL:N8(h.notify.bind,h.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"});j0(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=this.currentTurn?.fileDeliveryMode??this.getFileDeliveryMode(),X=f4({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(H),profile:C2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:D1},hostEnv:Z});return this.procSourceRevisions.set(X.process,X.sourceRevision),this.procFileDeliveryModes.set(X.process,H),X.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!==$)$$(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=Z1(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,H5(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()===U2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===U2($,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(R).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(R).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,V=!1,H=()=>{if(V)return;this.replaceFooterContent($,J(mW(Q,Y)))},X=null,z=()=>{if(V)return;let{nextDelayMs:W}=t$(Date.now()-Y,t1());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=i5({sessionName:this.sessionName,title:$,status:mW(Z,Y),template:J}),V=await c(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 J$(V)}catch(X){return K(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return d0(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>K9($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=K9($.title,`${Z} (${G0(J)})`);await O$($.cardId);let Q=await O0($.cardId,N.footer,this.footerElement(Y));N0($.cardId);let V=await D0($.cardId,h$({durationSec:J,suffix:Z}));if(Q&&V)await v0($.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&&VU(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?R(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 会话落盘确认失败: ${R(V)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${R(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,$$(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;$$(this.sessionName,[],null,null),b1(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=Z1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")b1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&r0(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"&&!s4(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await c(this.chatId,H$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!fW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await E(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{D5(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 O2();Q=this.spawnAgent()}catch(G){let B=`${this.backendLabel()} 启动失败: ${R(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,gW):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 ${OJ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(W.state==="error"||W.state==="exit"){let G=W.error?R(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 (${a6/1000}s)`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${a6/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 c(this.chatId,H$({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(`
255
- `))}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)}},OJ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${a6/1000}s`))},a6);$.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)k0($,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)k0(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){this.cancelFileDeliveries($),await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}cancelFileDeliveries($){let Z=!1;for(let J of this.fileDeliveries)Z=J.cancel($)||Z;return Z}async stopUnlocked($="已终止",Z={}){this.cancelFileDeliveries($);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: ${R(D)}`)});let X=this.waitForTurnCloses().catch((D)=>K(`session "${this.sessionName}": stop main-card close failed: ${R(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: ${R(D)}`)}let W=Q.conversationMaterializationBarrier?.();if(W){try{await W}catch(D){H=`Codex 会话落盘确认失败: ${R(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 会话落盘确认失败: ${R(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: ${R(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: ${R(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(R).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,J1(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 I=this.invalidateMissingCodexResume(z.sessionId,x,J),p=I?`❌ 旧会话不可恢复: ${R(x)};${I}`:`❌ 旧会话 cwd 校验失败: ${R(x)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Q?.(p),Y)await E(this.chatId,p);return!1}let W=z?.sessionId??null,G=X&&X.kind!=="fresh"?X.source.sessionId:W,B=G?R0(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?R0(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=(I)=>this.setStatusCard(q,I)}let P=Y&&!q,D=async(x)=>{if(q)await this.closeStatusCard(q,x)},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);this.bgResumePending=!1,this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.discardOrphanAssistant();for(let x of this.fileDeliveries)x.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((x)=>{K(`session "${this.sessionName}": restart current main-card close failed: ${R(x)}`)});let U=this.waitForTurnCloses().catch((x)=>K(`session "${this.sessionName}": restart main-card close failed: ${R(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 I=x.conversationMaterializationBarrier?.();if(I)try{await I}catch(l){_=`Codex 会话落盘确认失败: ${R(l)}`}if(j(x),$&&!X&&_&&!T&&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 p=x.conversationMaterializationFailure?.();if(p&&x.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${R(p)}`;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 b=(await Promise.allSettled([this.resetBackgroundTasks(),U])).filter((x)=>x.status==="rejected").map((x)=>x.reason);for(let x of b)K(`session "${this.sessionName}": restart terminal cleanup failed: ${R(x)}`);let v=M?this.finishProcStop(M,A):!0,y=[...A?[`kill=${R(A)}`]:[],...!v&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...b.map((x)=>`cleanup=${R(x)}`),..._?[`resume=${_}`]:[]];if(y.length>0&&H)try{J1(this.sessionName,H),this.pendingConversationMaterialization=H}catch(x){y.push(`pendingRestore=${R(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 g=X?.kind==="resume"||X?.kind==="fork";if($&&z||g){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 O2();x=this.spawnAgent(z??void 0)}catch(o){let K0=`❌ ${this.backendLabel()} 恢复失败: ${R(o)}`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${R(o)}`),Q?.(K0),P)await E(this.chatId,K0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(K0),!1}this.attachProc(x);let I=this.backendLabel(),p=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(x,gW):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${I} 恢复启动`:`⏳ 等待 ${I} init 确认`);let l,F=null;try{x.sendInitialize(),l=x.initializationPromise?.()}catch(o){l=void 0,F=o}let C=F?{state:"error",error:F}:this.selectedProvider==="claude"?await p:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{K(`session "${this.sessionName}": codex resume init still pending after ${OJ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${I} init 确认 thread=${B}`))});if(C.state==="error"||C.state==="exit"||C.state==="timeout"){let o=C.state==="error"?this.invalidateMissingCodexResume(G,C.error,J):null,K0=[C.error?R(C.error):C.state,o].filter(Boolean).join(";");K(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${K0}`);let S9=await this.stopOwnedProc(x,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,J2=C.state==="timeout"?`❌ ${I} 恢复超时${S9}`:`❌ ${I} 恢复失败: ${K0}${S9}`;if(Q?.(J2),P)await E(this.chatId,J2);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(J2),!1}if(this.proc!==x||!x.isAlive()){let o=`❌ ${I} 恢复期间已退出`;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(C.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&C.state==="ready"?`✅ 已准备恢复上一会话 thread=${B}`:`✅ 已恢复上一会话 thread=${B}`));if(Q?.(d),P)await E(this.chatId,d);if(this.status=C.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),C.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: ${R(o)}`),await w(this.chatId,`⚠️ ${d}
256
- 状态卡收尾失败: ${R(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()=>{j0($,this.selectedProvider,this.workDir);let J=n4(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)J1(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)J1(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{J1(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Q,V],`fork start and pending-intent restore failed: ${R(Q)}; ${R(V)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{j0($,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=d4(this.sessionName).slice(),z=i4(this.sessionName),W=n4(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,k2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=H,H)l4(this.sessionName,H);else k2(this.sessionName,this.selectedProvider);$$(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)$$(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,U=this.proc&&this.proc!==Q?this.proc:null;if(U)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(b){T=b}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!T)T=Error("replacement process stop was not confirmed");let M=null;if(A)try{_()}catch(b){M=b}let S=[D,...T?[T]:[],...M?[M]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback launch and cleanup failed: ${S.map(R).join("; ")}`)}if(!P)return _(),!1;if(Y)try{if(!j)$$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(D){let T=null,U=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(b){T=b}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!T)T=Error("replacement process stop was not confirmed");let M=null;if(A)try{_()}catch(b){M=b}let S=[D,...T?[T]:[],...M?[M]:[]];if(S.length===1)throw D;throw AggregateError(S,`rollback branch commit failed: ${S.map(R).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){K$.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 Y5(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${R(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(...HZ(J.name,J.input));return Z}worktreeProjectName(){return B1(this)}worktreeProjectDir(){return Z4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return LW(this,$)}delegatedAgentDeveloperInstructions($){return qW(this,$)}worktreeInstructionLoadedNotice(){return DJ(this)}withWorktreeInstructionNotice($){return PW(this,$)}worktreeExtraInstruction(){return T9(this)}runWorktreeCommand($,Z){return DW(this,$,Z)}showWorktrees(){return FJ(this)}showTasklistPanel(){return Iz(this)}showAgentIdentityPanel($=""){return Sz(this,$)}onAgentIdentityPage($,Z,J){return bz($,Z,J)}onTasklistEnable(){return gz(this)}onTasklistDeletePrompt($){return mz(this,$)}onTasklistDeleteConfirm($){return pz(this,$)}runCompactCommand(){return Pz(this)}showModelPanel(){return Fz(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>Tz(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>QJ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return YJ(this,$,Z)}onModelPage($,Z,J){return v6(this,$,Z,J)}onModelAddOpen($,Z){return Uz(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>Mz(this,$,Z,J,Y))}onModelPanelCancel($=""){return Rz(this,$)}onModelCustomPrompt($,Z,J=""){return Az(this,$,Z,J)}consumeModelCustomMessage($,Z){return Oz(this,$,Z)}onWorktreeDisband($){return UW(this,$)}showForkList($=""){return EW(this,$)}showBackList($=""){return xW(this,$)}showResumeList($=""){return SW(this,$)}runBtwCommand($){return bW(this,$)}runByeCommand(){return CW(this)}onForkSelect($,Z,J=""){return kW(this,$,Z,J)}onBackSelect($,Z,J=""){return yW(this,$,Z,J)}onResumeSelect($,Z,J=""){return wW(this,$,Z,J)}runCommand($,Z="",J){return Lz(this,$,Z,J)}getFileDeliveryMode(){return s2.mode(this.chatId)}runFileDeliveryCommand($,Z){return oz(this.chatId,this.sessionName,Z,$,{get:(J)=>s2.get(J),enable:(J,Y)=>s2.enable(J,Y),disable:(J)=>s2.disable(J),sendCard:(J)=>c(this.chatId,J),reportError:async(J)=>{if(K(`session "${this.sessionName}": ${J}`),!await E(this.chatId,J))throw Error(J)}})}async buildConsoleOpts($,Z){let J=await RH(),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:[...K$.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return n5(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:D8(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 tH();else Z.usage=await E1(this.codexAccountId());if(!await O0($,N.consoleUsage,B9(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: ${R(V)}`)}let Q=!1;try{Q=await D0($,{config:{streaming_mode:!1}})}catch(V){K(`session "${this.sessionName}": ${Z} streaming-off failed: ${R(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 v0($)}catch(V){return K(`session "${this.sessionName}": ${Z} dispose failed: ${R(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 O$($.cardId);let Q=await O0($.cardId,N.footer,W6(Y,N.footer)),V=await Y1($.cardId,z6(Y),{type:"insert_after",targetElementId:N.footer}),H=await Y1($.cardId,G6(Y.sysinfo),{type:"insert_after",targetElementId:N.consoleProjects}),X=await Y1($.cardId,B9(Y),{type:"insert_after",targetElementId:N.consoleHost});if(!Q||!V||!H||!X){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}N0($.cardId),await D0($.cardId,h$({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await c(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await J$(Z),d0(J,4)}catch(Y){K(`session "${this.sessionName}": console card conversion failed: ${R(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>K(`session "${this.sessionName}": console async update rejected: ${R(J)}`))}interrupt(){if(!this.proc)return;K(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){let J=this.currentTurn,Y=J?J.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),Q=this.procFileDeliveryModes.get($),V=Q===Y?"":`${$W(Y)}
257
-
258
- `;this.procFileDeliveryModes.set($,Y),this.pendingUserMessageCount++;try{$.sendUserText(V+Z,[])}catch(H){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),Q===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,Q);throw H}}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 O$(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(" ")+`
259
- `:"")+$,z=(W)=>{this.pendingReactionIds.set(W,""),(async()=>{let G=await l0(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 k0(W,G)})().catch((G)=>{K(`session "${this.sessionName}": reaction tracking failed: ${R(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 TX(this)}refreshPendingAsks(){R6(this)}askBlockReason($){return d2(this,$)}onMultiMessageInbound($,Z,J,Y){return QX(this,$,Z,J,Y)}clearMultiMsgBuffer($){MZ(this,$)}onAskMessageAnswer($,Z,J){return EX(this,$,Z,J)}onAskAnswer($,Z,J,Y){return xX(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return kZ(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return wX(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=Z1(this.sessionName,"codex");if(k2(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=RJ(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=Z1(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{k2(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${R(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=${R0($)}`;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{l4(this.sessionName,V)}catch(X){let z=`会话恢复点持久化失败: ${R(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 J1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${R(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(X3(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(!R1(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{K(`session "${this.sessionName}": background settle failed: ${R(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{K(`session "${this.sessionName}": background open failed: ${R(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=B3(Z,Date.now(),t1()),Y=await c(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))K(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await J$(Y)}catch(V){K(`session "${this.sessionName}": background card id_convert failed: ${V}`);return}if(d0(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}`),!R1(this.backgroundTasks)){this.settleBackgroundCard().catch((V)=>{K(`session "${this.sessionName}": background settle-after-open failed: ${R(V)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!R1(this.backgroundTasks))return;let Z=t1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(t0(Q))continue;let V=t$(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=t1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),Y1($.cardId,L2(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 J0($.cardId,N4.panel(Y.id),L2(Y,Z,J));w1($.cardId,X8(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!t0($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>t0(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: ${R(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 O$($.cardId),await A$($.messageId,z8(Z)),N0($.cardId),!await D0($.cardId,h$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await v0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!t0(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===$&&R1(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 O$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(t0).map((V)=>V.id)),Y=J.size;if(Y>0)await A$($.messageId,z8(Z));else await A$($.messageId,_3());if(N0($.cardId),!await D0($.cardId,h$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await v0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((V)=>!J.has(V.id)||!t0(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: ${R(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: ${R(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: ${R(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)k0(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: ${R(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 会话落盘确认失败,未写恢复点: ${R(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)c(this.chatId,H$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
260
- `),hint:"详情:codex-accounts"})).catch((W)=>{K(`session "${this.sessionName}": 账号诊断卡失败: ${R(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")oQ(X,r0($))}),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(W3({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}if(CX(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(K3({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}kX(this,X,z,W,B)}),H("can_use_tool",(X)=>{vX(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,T=!1,U=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?`⚠️ ${U} ${P},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)D=`⚠️ ${U} ${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((M)=>{K(`session "${this.sessionName}": result card close failed: ${R(M)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((M)=>{K(`session "${this.sessionName}": mid-turn drain failed: ${R(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(Q3(this.bgStore(),{...X,tool_use_id:z})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(X)=>{this.applyBgStore(V3(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(H3(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(z3(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(G3(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 会话落盘确认失败: ${R(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: ${R(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: ${R(q)}`)});let j=this.waitForTurnCloses().catch((q)=>{K(`session "${this.sessionName}": process-exit main-card close failed: ${R(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: ${R(P.reason)}`);if(!W)await E(this.chatId,`⚠️ ${G} 异常退出 (${B})。回复任意消息将重新启动。`)}).catch((q)=>{K(`session "${this.sessionName}": process-exit cleanup rejected: ${R(q)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?p7(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=c7(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 l8(Z)}contextLimitForDisplay($=this.proc){return d8($?.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: ${R(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(`
261
-
262
- `),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)k0(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)k0(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)} 接收消息失败: ${R(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 O0($,N.footer,this.footerElement(Z)):!0;N0($);let Q=await D0($,h$({suffix:Z}));if(Y&&Q){await v0($);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: ${R($)}`)})}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&R1(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=o8({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 c(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 J$(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 d0(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,fileDeliveryMode:J==="user_message"&&this.pendingUserMessageCount===0?void 0:this.proc?this.procFileDeliveryModes.get(this.proc):void 0};if(d0(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: ${R(q)}`)})}return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&e4($.cardId)<BU)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(!t4(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=${e4(Z)}`);let H=o8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),X=await c(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 J$(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}d0(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=N.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=P,$.currentAssistantText=B,$.segmentTexts.set(P,B)}if(B)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)A0($.cardId,m1(this.taskBoard),{type:"insert_before",targetElementId:N.footer});if($.planLiveInserted)A0($.cardId,J9($.planSteps,$.planExplanation,N.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?N.taskBoardLive:N.footer});for(let P of $.contextCompactionPending.values()){if(P.cardId!==Z)continue;P.cardId=z,P.created=!1,P.createFailure=void 0;let D=N.contextCompact(P.i);P.createPromise=w2(z,Z9(P.i,P.notice,D),{type:"insert_before",targetElementId:T0($)}).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(!y2(Z,P))continue;let T=$.assistantSegmentCount++,U=N.assistant(T);$.segmentTexts.set(U,D),await this.addCompletedAssistantSegment($,U,D)}vZ(this,Z,z,J,Y,$),await O$(Z),vZ(this,Z,z,J,Y,$);let j=new Set([N.taskBoardLive,N.planLive,...[...$.contextCompactionPending.values()].map((P)=>N.contextCompact(P.i))]);if(G)j.add(G);for(let P of J.values())if(P.output==null)j.add(N.tool(P.i));if(yV(Z).some((P)=>!j.has(P)))$.cardCapacityFailures.clear();await O$(z);try{await wZ($,Z);let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await O$(Z);let D=$.mathRendered?.get(Z);for(let[M,S]of _){if(G&&B&&M===G)continue;if(y2(Z,M))continue;if(D?.has(M))continue;await J0(Z,M,this.completedAssistantElement(M,S))}let T=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",U=await O0(Z,N.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${T}`)),{notifyCardFailure:!1});N0(Z);let A=await D0(Z,h$({suffix:"\uD83D\uDCE8 转下一张"}));if(U&&A)await v0(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=N.planUpdate($.planUpdateCount++);A0(Z,x5($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:T0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=N.goalUpdate(Z.goalUpdateCount++);A0(Z.cardId,S5($,J),{type:"insert_before",targetElementId:T0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=N.goalUpdate($.goalUpdateCount++);A0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
263
-
264
- 已清除`},{type:"insert_before",targetElementId:T0($)})}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<o6){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<o6||!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<o6){K(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let U=XU($);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=N.contextCompact(A),b={i:A,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};b.createPromise=w2(M,Z9(A,$,S),{type:"insert_before",targetElementId:T0(J)}).then((v)=>{if(b.cardId===M)b.created=v.landed,b.createFailure=v.failure;return v.landed}),J.contextCompactionPending.set(U,b),K(`session "${this.sessionName}": context compaction start #${A+1} key=${U}`),w1(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<o6){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:zU(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 _=WU(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=N.contextCompact(q),T=Z9(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 Y1(A,T,{type:"insert_before",targetElementId:T0(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 O0(A,D,T);else{if(kV(G.createFailure?.code,G.createFailure))wV(A,D),U=await O0(A,D,T,{notifyCardFailure:!1});if(!U)U=await Y1(A,T,{type:"insert_before",targetElementId:T0(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: ${R(U)}`)}),w1(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>_U){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?N.taskBoardLive:N.footer;Z.planLiveInserted=!0,A0(Z.cardId,J9(Z.planSteps,Z.planExplanation,N.planLive),{type:"insert_before",targetElementId:J})}else J0(Z.cardId,N.planLive,J9(Z.planSteps,Z.planExplanation,N.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&&a8(Z)===a8(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=N.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);w1(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
248
+ ${G}`)}return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1}}function MJ($){if(!n1($))throw Error(`project directory does not exist: ${$}`);let Z=T0($,["rev-parse","--show-toplevel"]).trim();if(DJ(Z)!==DJ($))throw Error(`${$} is not the git repository root (${Z})`)}function UW($,Z){let J=T0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function gF($,Z,J){let Y=mF($);if(!Y?.startsWith(s2))return null;let Q=Y.slice(s2.length);if(!a1(Q))throw Error(`invalid worktree branch "${Y}"`);let V=e2(Z,J,Q);if(d6($)!==d6(V))return null;let H=cF($,pF(Q));return H?{path:H,slug:Q}:null}function mF($){if(!n1($))return null;try{return T0($,["branch","--show-current"]).trim()||null}catch(Z){if(lF(Z))return null;throw Z}}function pF($){return $.split("-",1)[0]??$}function cF($,Z){let J=`agents.${Z}.md`,Y=vF($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?jW($,Y[0]):null}function uF($,Z){try{return T0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function AW($,Z,J){let Y=T0($,["rev-parse",Z]).trim(),Q=T0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(_W($,Z,"HEAD"))return"merged";if(_W($,"HEAD",Z))return"active";return"stale"}function _W($,Z,J){try{return T0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function UJ($){let Z=new Map,J=T0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
249
+ `)){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 T0($,Z){try{return yF("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(AJ(J))}}function AJ($){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 lF($){return/not a git repository/i.test(AJ($))}var s2="work/",IF,l6;var OW=O(()=>{IF=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,l6=new Map});function z1($){return LW(O$($.sessionName)??$.sessionName)}function $4($){return W6(z1($))}function NW($){let Z=O$($.sessionName)??$.sessionName,J=z1($),Y=W6(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return e2(Y,J,Q)}function TW($,Z,J=$.currentProvider()){let Y=GW(J,Z),Q=R9($);return Q?`${Y}
250
+ ${Q}`:Y}function EW($,Z){return R9($)??""}function OJ($){return R9($)?"已载入wt特殊约定":null}function xW($,Z){let J=OJ($);return J?`${Z}
251
+ ${J}`:Z}function R9($){let Z=z1($),J=PW($.workDir,$4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
252
+ `)}async function SW($,Z,J){if(!Z){await RJ($);return}let Y=a1(Z);if(!Y){await E($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await E($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=z1($),V=$4($);try{await i6(V,async()=>{let H;try{H=FW(V,Q,Y)}catch(X){await E($.chatId,`❌ wt 失败: ${N(X)}`);return}try{let X=await XZ(H.chatName,J),z=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await c($.chatId,o4({slug:Y,branch:H.branch,status:z})))await v($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await c(X.chatId,o4({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await v(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await E($.chatId,`❌ wt 已建,拉群失败: ${N(X)}`)}})}catch(H){await E($.chatId,`❌ wt 失败: ${N(H)}`)}}async function CW($,Z){let J=z1($),Y=$4($);return await i6(Y,async()=>{return await iF(J,Y,Z)})}async function iF($,Z,J){let Y=DW(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,V=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await K6();return L5({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 RJ($){try{let Z=await CW($);if(!await c($.chatId,Z))await v($.chatId,"❌ wt 列表失败")}catch(Z){await E($.chatId,`❌ wt 列表失败: ${N(Z)}`)}}async function RW($,Z,J,Y){try{return{ok:Z,message:J,card:await CW($,{type:Y,content:J})}}catch(Q){let V=`列表刷新失败: ${N(Q)}`;return K(`session "${$.sessionName}": wt action panel refresh failed: ${N(Q)}`),{ok:!1,message:`${J}
253
+ ${V}`,card:o4({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function bW($,Z){let J=a1(Z);if(!J)return RW($,!1,"❌ 名称无效","error");let Y=z1($),Q=$4($),V;try{V=await i6(Q,async()=>{let H=t2(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};FJ(Q,Y,J);let X=await WZ(H),z=MW(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",z.branch].join(`
254
+ `),type:"success"}})}catch(H){V={ok:!1,message:`❌ 解散 ${J} 失败: ${N(H)}`,type:"error"}}return RW($,V.ok,V.message,V.type)}var kW=O(()=>{u6();t0();t();f();OW()});import{closeSync as aF,openSync as oF,readSync as rF,readdirSync as sF,statSync as tF}from"node:fs";import{randomUUID as TJ}from"node:crypto";import{join as eF}from"node:path";function a6($){return O$($.sessionName)??$.sessionName}function vW($){let Z=$Z($,NJ);return NJ.add(Z),Z}function wW($){NJ.delete($)}function Z4($){let Z=yW.get($);if(!Z)Z=new Map,yW.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let V=Q.status==="consumed"?JM:ZM,H=Q.consumedAt??Q.createdAt;if(J-H>V)Z.delete(Y)}return Z}function QM($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function fW($,Z,J,Y){let Q={id:TJ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:a6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return Z4($).set(Q.id,Q),Q}function EJ($,Z,J,Y,Q){let V=Z4($).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||!QM(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 n6($){$.status="consumed",$.consumedAt=Date.now()}function VM($){return{kind:"fork",source:$.source,through:$}}function HM($){return J9($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function XM($){let Z=Y9($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return _0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function zM($){let Z=K8($),J;try{J=sF(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(Y2("claude",V))continue;let H=eF(Z,Q),X;try{X=tF(H).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:V,cwd:$,preview:GM(H),ts:X})}return Y.sort((Q,V)=>V.ts-Q.ts)}function WM($){let Z=$.slice().sort((Q,V)=>V.ts-Q.ts),J=Date.now()-$M,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(YM,Math.max(10,Y)))}function GM($){let Z="",J=null;try{J=oF($,"r");let Q=Buffer.alloc(65536),V=rF(J,Q,0,65536,0);Z=Q.subarray(0,V).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)aF(J)}let Y="";for(let Q of Z.split(`
255
+ `)){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=KM(H.message);if(X)Y=X}}return Y.slice(0,80)}function KM($){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 hW($,Z,J){if(!J){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=HM($),Q=XM($),V=new Map,H=[];for(let G=0;G<Y.length;G++){let B=Y[G];if(G===0&&Q===null)continue;let _=TJ(),j=G===0?Q:VM(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=fW($,Z,J,V),z=P5({projectName:a6($),panelId:X.id,mode:Z,entries:H}),W;try{W=await c($.chatId,z)}catch(G){throw Z4($).delete(X.id),G}if(!W)Z4($).delete(X.id),await v($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function IW($,Z){return hW($,"fork",Z)}function gW($,Z){return hW($,"back",Z)}async function mW($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():zM($.workDir)}catch(z){await v($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=WM(J).map((z)=>{let W=TJ();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=fW($,"resume",Z,Y),H=D5({projectName:a6($),panelId:V.id,entries:Q}),X;try{X=await c($.chatId,H)}catch(z){throw Z4($).delete(V.id),z}if(!X)Z4($).delete(V.id),await v($.chatId,"❌ rs 历史列表发送失败")}async function pW($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await E($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=vW(a6($));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{wW(J)}if(!Y.ok){await E($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await E($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function cW($){if(!O$($.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 uW($,Z,J,Y){let Q=EJ($,"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=vW(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{wW(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{n6(V)}}async function lW($,Z,J,Y){let Q=EJ($,"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 c($.chatId,F5({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?` ${O0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{n6(V)}}async function dW($,Z,J,Y){let Q=EJ($,"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 n6(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{n6(V)}}var $M=86400000,ZM=1800000,JM=3600000,YM=40,yW,NJ;var iW=O(()=>{t();t0();f();j2();L4();D1();yW=new WeakMap,NJ=new Set});import{existsSync as nW}from"node:fs";import{randomBytes as xJ,timingSafeEqual as _M}from"node:crypto";import{isAbsolute as jM}from"node:path";function CJ($,Z=new Set){if($ instanceof W2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=CJ(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return CJ($.cause,Z);return null}function LM($){return $.itemId||$.turnId||"__latest__"}function aW($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function qM($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function PM($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function s6(){return h.runtime?.live_elapsed??"bucket"}function sW($,Z){return`${$} (${K2(Date.now()-Z,s6()).label})`}var oW="Thinking...",DM="Writing...",FM="Working...",SJ=1e4,o6=720000,MM=50,UM=256,r6=1e4,rW=250,B$;var GJ=O(()=>{L4();P4();B0();F1();L3();B0();k0();f3();FZ();Y0();m0();g2();j2();v$();t0();t();f();V0();X5();k$();q9();OZ();RZ();qX();SX();lX();T6();nX();Ez();Sz();Iz();lz();ez();VW();XW();u6();kW();iW();D1();B$=class B${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;procFileDeliveryModes=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];agentCards;backgroundOwner=xJ(16).toString("hex");backgroundRefreshTimer=null;backgroundSync=null;backgroundWriteError=null;lastMainTaskToolUseId=null;nativeAgentTools=new Map;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;fileDeliveries=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;this.agentCards=J.agentCards??tH(),B$.all.add(this);let Y=YZ($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=P$(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=J1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)K(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=Q9($);if(V)if(this.selectedProvider!=="claude")e0($,[],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(a0(this.proc)).name}:{}}}get workDir(){return NW(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 q8(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?a0(this.proc):this.codexStartAccountOverride??k.selected(this.sessionName)}tokenSource($){let Z=P$($);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()===u?{}:{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=P$($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)e0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=J1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,b1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??u;if($.codexAccountAutomatic)k.selectAuto(this.sessionName);else if(k.selected(this.sessionName)!==J)k.select(this.sessionName,J)}dshEffortForSpawn(){if(K0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&q$($,this.selectedModel??$.defaultModel);if(!Z||!K0(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 Q2({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!Y2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!z9(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 G2({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: ${N(V)}; ${N(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=B8(this.workDir,$.sessionId);if(!nW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${O0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!z9(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 G2({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=${N(V)}; cleanup=${N(H)}`);if(V)throw V;if(H)throw H}return _0({kind:"resume",source:Z},this.selectedProvider,this.workDir),Z9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...B$.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 o0(this.selectedEffort)?this.selectedEffort:O4}return O4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&D0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=q$($,this.selectedModel??$.defaultModel);if(!D0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return d$}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??q$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?d$:O4)}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"?d$:O4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return Q0($,R.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:R.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return p3($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return L$($)}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=xJ(32).toString("base64url");let Z={LODESTAR_AGENT_URL:O8(h.notify.bind,h.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=this.currentTurn?.fileDeliveryMode??this.getFileDeliveryMode(),X=f4({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(H),profile:y2(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},hostEnv:Z});return this.procSourceRevisions.set(X.process,X.sourceRevision),this.procFileDeliveryModes.set(X.process,H),X.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!==$)e0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let V=P$(this.selectedTokenSourceId);if(V)this.selectedModel=Z||null,this.selectedEffort=J??q$(V,Z||V.defaultModel)?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=J1(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,JZ(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(N).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(N).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,V=!1,H=()=>{if(V)return;this.replaceFooterContent($,J(sW(Q,Y)))},X=null,z=()=>{if(V)return;let{nextDelayMs:W}=K2(Date.now()-Y,s6());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=z5({sessionName:this.sessionName,title:$,status:sW(Z,Y),template:J}),V=await c(this.chatId,Q);if(!V)return K(`session "${this.sessionName}": status card send failed title=${$}`),await v(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await G$(V)}catch(X){return K(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await v(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return Z$(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>n4($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=n4($.title,`${Z} (${F0(J)})`);await Q1($.cardId);let Q=await A0($.cardId,R.footer,this.footerElement(Y));y0($.cardId);let V=await R0($.cardId,R1({durationSec:J,suffix:Z}));if(Q&&V)await J$($.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 v(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()}attachProc($){this.invalidateTurnOpen(),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.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&&_M(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?N(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 会话落盘确认失败: ${N(V)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${N(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,e0(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;e0(this.sessionName,[],null,null),b1(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=J1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")b1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&a0(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"&&!z9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await c(this.chatId,K$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!nW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await E(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{jZ(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()} 启动失败: ${N(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,rW):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 ${SJ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(W.state==="error"||W.state==="exit"){let G=W.error?N(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 (${o6/1000}s)`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${o6/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 c(this.chatId,K$({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(`
256
+ `))}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)}},SJ),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${o6/1000}s`))},o6);$.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)b0($,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)b0(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){this.cancelFileDeliveries($),await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}cancelFileDeliveries($){let Z=!1;for(let J of this.fileDeliveries)Z=J.cancel($)||Z;return Z}async stopUnlocked($="已终止",Z={}){this.cancelFileDeliveries($);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.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((D)=>{K(`session "${this.sessionName}": stop current main-card close failed: ${N(D)}`)});let X=this.waitForTurnCloses().catch((D)=>K(`session "${this.sessionName}": stop main-card close failed: ${N(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: ${N(D)}`)}let W=Q.conversationMaterializationBarrier?.();if(W){try{await W}catch(D){H=`Codex 会话落盘确认失败: ${N(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 会话落盘确认失败: ${N(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: ${N(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: ${N(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(N).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,Y1(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 I=this.invalidateMissingCodexResume(z.sessionId,x,J),p=I?`❌ 旧会话不可恢复: ${N(x)};${I}`:`❌ 旧会话 cwd 校验失败: ${N(x)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Q?.(p),Y)await E(this.chatId,p);return!1}let W=z?.sessionId??null,G=X&&X.kind!=="fresh"?X.source.sessionId:W,B=G?O0(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?O0(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=(I)=>this.setStatusCard(q,I)}let P=Y&&!q,D=async(x)=>{if(q)await this.closeStatusCard(q,x)},T=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||X3(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let x of this.fileDeliveries)x.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((x)=>{K(`session "${this.sessionName}": restart current main-card close failed: ${N(x)}`)});let M=this.waitForTurnCloses().catch((x)=>K(`session "${this.sessionName}": restart main-card close failed: ${N(x)}`)),A=null,U=null;if(this.proc){let x=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(x.provider)}`),U=x,this.beginProcStop(x);let I=x.conversationMaterializationBarrier?.();if(I)try{await I}catch(l){_=`Codex 会话落盘确认失败: ${N(l)}`}if(j(x),$&&!X&&_&&!T&&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 p=x.conversationMaterializationFailure?.();if(p&&x.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${N(p)}`;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(),M])).filter((x)=>x.status==="rejected").map((x)=>x.reason);for(let x of C)K(`session "${this.sessionName}": restart terminal cleanup failed: ${N(x)}`);let w=U?this.finishProcStop(U,A):!0,y=[...A?[`kill=${N(A)}`]:[],...!w&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...C.map((x)=>`cleanup=${N(x)}`),..._?[`resume=${_}`]:[]];if(y.length>0&&H)try{Y1(this.sessionName,H),this.pendingConversationMaterialization=H}catch(x){y.push(`pendingRestore=${N(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 g=X?.kind==="resume"||X?.kind==="fork";if($&&z||g){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 G0=`❌ ${this.backendLabel()} 恢复失败: ${N(o)}`;if(K(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${N(o)}`),Q?.(G0),P)await E(this.chatId,G0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(G0),!1}this.attachProc(x);let I=this.backendLabel(),p=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(x,rW):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${I} 恢复启动`:`⏳ 等待 ${I} 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 p:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{K(`session "${this.sessionName}": codex resume init still pending after ${SJ/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${I} 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,G0=[b.error?N(b.error):b.state,o].filter(Boolean).join(";");K(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${G0}`);let E9=await this.stopOwnedProc(x,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,t1=b.state==="timeout"?`❌ ${I} 恢复超时${E9}`:`❌ ${I} 恢复失败: ${G0}${E9}`;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=`❌ ${I} 恢复期间已退出`;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: ${N(o)}`),await v(this.chatId,`⚠️ ${d}
257
+ 状态卡收尾失败: ${N(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=Q9(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)Y1(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)Y1(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{Y1(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Q,V],`fork start and pending-intent restore failed: ${N(Q)}; ${N(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=J9(this.sessionName).slice(),z=Y9(this.sessionName),W=Q9(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,v2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=H,H)Z9(this.sessionName,H);else v2(this.sessionName,this.selectedProvider);e0(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)e0(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(N).join("; ")}`)}if(!P)return _(),!1;if(Y)try{if(!j)e0(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(N).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){B$.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 e5(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${N(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(...A5(J.name,J.input));return Z}worktreeProjectName(){return z1(this)}worktreeProjectDir(){return $4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return TW(this,$)}delegatedAgentDeveloperInstructions($){return EW(this,$)}worktreeInstructionLoadedNotice(){return OJ(this)}withWorktreeInstructionNotice($){return xW(this,$)}worktreeExtraInstruction(){return R9(this)}runWorktreeCommand($,Z){return SW(this,$,Z)}showWorktrees(){return RJ(this)}showTasklistPanel(){return oz(this)}showAgentIdentityPanel($=""){return mz(this,$)}onAgentIdentityPage($,Z,J){return pz($,Z,J)}onTasklistEnable(){return rz(this)}onTasklistDeletePrompt($){return sz(this,$)}onTasklistDeleteConfirm($){return tz(this,$)}runCompactCommand(){return xz(this)}showModelPanel(){return Cz(this)}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>hz(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>WJ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return zJ(this,$,Z)}onModelPage($,Z,J){return f6(this,$,Z,J)}onModelAddOpen($,Z){return bz(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>kz(this,$,Z,J,Y))}onModelPanelCancel($=""){return wz(this,$)}onModelCustomPrompt($,Z,J=""){return yz(this,$,Z,J)}consumeModelCustomMessage($,Z){return vz(this,$,Z)}onWorktreeDisband($){return bW(this,$)}showForkList($=""){return IW(this,$)}showBackList($=""){return gW(this,$)}showResumeList($=""){return mW(this,$)}runBtwCommand($){return pW(this,$)}runByeCommand(){return cW(this)}onForkSelect($,Z,J=""){return uW(this,$,Z,J)}onBackSelect($,Z,J=""){return lW(this,$,Z,J)}onResumeSelect($,Z,J=""){return dW(this,$,Z,J)}runCommand($,Z="",J){return Tz(this,$,Z,J)}getFileDeliveryMode(){return r2.mode(this.chatId)}runFileDeliveryCommand($,Z){return HW(this.chatId,this.sessionName,Z,$,{get:(J)=>r2.get(J),enable:(J,Y)=>r2.enable(J,Y),disable:(J)=>r2.disable(J),sendCard:(J)=>c(this.chatId,J),reportError:async(J)=>{if(K(`session "${this.sessionName}": ${J}`),!await E(this.chatId,J))throw Error(J)}})}async buildConsoleOpts($,Z){let J=await uV(),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:[...B$.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:q8(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 VX();else Z.usage=await A1(this.codexAccountId());if(!await A0($,R.consoleUsage,a4(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: ${N(V)}`)}let Q=!1;try{Q=await R0($,{config:{streaming_mode:!1}})}catch(V){K(`session "${this.sessionName}": ${Z} streaming-off failed: ${N(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 J$($)}catch(V){return K(`session "${this.sessionName}": ${Z} dispose failed: ${N(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 Q1($.cardId);let Q=await A0($.cardId,R.footer,l8(Y,R.footer)),V=await w1($.cardId,u8(Y),{type:"insert_after",targetElementId:R.footer}),H=await w1($.cardId,d8(Y.sysinfo),{type:"insert_after",targetElementId:R.consoleProjects}),X=await w1($.cardId,a4(Y),{type:"insert_after",targetElementId:R.consoleHost});if(!Q||!V||!H||!X){await v(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}y0($.cardId),await R0($.cardId,R1({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await c(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await G$(Z),Z$(J,4)}catch(Y){K(`session "${this.sessionName}": console card conversion failed: ${N(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>K(`session "${this.sessionName}": console async update rejected: ${N(J)}`))}interrupt(){if(!this.proc)return;K(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){let J=this.currentTurn,Y=J?J.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),Q=this.procFileDeliveryModes.get($),V=Q===Y?"":`${KW(Y)}
258
+
259
+ `;this.procFileDeliveryModes.set($,Y),this.pendingUserMessageCount++;try{$.sendUserText(V+Z,[])}catch(H){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),Q===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,Q);throw H}}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 Q1(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(" ")+`
260
+ `:"")+$,z=(W)=>{this.pendingReactionIds.set(W,""),(async()=>{let G=await u0(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 b0(W,G)})().catch((G)=>{K(`session "${this.sessionName}": reaction tracking failed: ${N(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 hX(this)}refreshPendingAsks(){N6(this)}askBlockReason($){return l2(this,$)}onMultiMessageInbound($,Z,J,Y){return LX(this,$,Z,J,Y)}clearMultiMsgBuffer($){TZ(this,$)}onAskMessageAnswer($,Z,J){return IX(this,$,Z,J)}onAskAnswer($,Z,J,Y){return gX(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return hZ(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=J1(this.sessionName,"codex");if(v2(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=CJ(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=J1(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{v2(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${N(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=${O0($)}`;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{Z9(this.sessionName,V)}catch(X){let z=`会话恢复点持久化失败: ${N(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)v(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)v(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 Y1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${N(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(G3(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}hasPendingAgentTool(){return this.nativeAgentTools.size>0}onBackgroundTaskChanged($=!1){if(!this.backgroundTasks.length)return;if($){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull().catch((Z)=>this.reportBackgroundWriteFailure(Z))}else this.scheduleBackgroundRefresh()}scheduleBackgroundRefresh(){if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull().catch(($)=>this.reportBackgroundWriteFailure($))},1500)}refreshBackgroundCardFull(){let $=this.backgroundOwner,Z=[...this.backgroundTasks],J=this.agentCards.syncBackground(this.chatId,$,Z),Y;return Y=J.then(()=>{this.backgroundWriteError=null}).finally(()=>{if(this.backgroundSync===Y)this.backgroundSync=null}),this.backgroundSync=Y,Y}async reportBackgroundWriteFailure($){let Z=N($);if(K(`session "${this.sessionName}": delegation panel update failed: ${Z}`),this.backgroundWriteError===Z)return;this.backgroundWriteError=Z,await v(this.chatId,`⚠️ 委派面板更新失败:${Z}`)}async resetBackgroundTasks(){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null;let $=Date.now();if(this.backgroundTasks=this.backgroundTasks.map((Z)=>Q$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$}),this.pendingBgTasks=[],this.backgroundSync)try{await this.backgroundSync}catch(Z){K(`session "${this.sessionName}": retrying terminal delegation update after: ${N(Z)}`)}if(await this.refreshBackgroundCardFull(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null,this.agentCards.releaseBackground(this.backgroundOwner),this.backgroundOwner=xJ(16).toString("hex"),this.backgroundTasks=[],this.nativeAgentTools.clear(),this.lastMainTaskToolUseId=null}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: ${N(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: ${N(H)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen();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: ${N(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)b0(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)v(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: ${N(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 会话落盘确认失败,未写恢复点: ${N(W)}`,B=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,K(`session "${this.sessionName}": ${G} thread=${X} source=${z}`),B)v(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)c(this.chatId,K$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
261
+ `),hint:"详情:codex-accounts"})).catch((W)=>{K(`session "${this.sessionName}": 账号诊断卡失败: ${N(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")tQ(X,a0($))}),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(K3({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}if(!G&&(z==="Task"||z==="Agent"||$.provider==="dsh"&&(z==="subagent"||z==="subagent_fork"))){let B=this.currentTurn;if(B)this.startWorkingFooter(B),this.finalizeCurrentAssistantSegment(),B.openBatchI=null,B.taskCreateI=null,B.taskUpdateI=null;if(this.onMainThreadAdvance(),this.nativeAgentTools.set(X,{confirmed:!1,input:W}),$.provider==="claude")this.lastMainTaskToolUseId=X,this.applyBgStore(N4(this.bgStore(),{task_id:X,tool_use_id:X,task_type:"subagent",description:W?.description||W?.name||"子 Agent",prompt:W?.prompt,subagent_type:W?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(cX(this,X,z,W),!G)this.onMainThreadAdvance()}),H("tool_result",({tool_use_id:X,content:z,is_error:W,parentToolUseId:G,input:B})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(_3({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,z,W)),this.onBackgroundTaskChanged();return}let _=!G&&this.nativeAgentTools.get(X);if(_){if(this.nativeAgentTools.delete(X),this.lastMainTaskToolUseId===X)this.lastMainTaskToolUseId=null;if(W||$.provider==="claude"&&!_.confirmed&&_.input?.run_in_background!==!0){let j=typeof z==="string"?z:Array.isArray(z)?z.map((P)=>typeof P?.text==="string"?P.text:JSON.stringify(P)).join(`
262
+ `):JSON.stringify(z)??"MISS",q=this.backgroundTasks.find((P)=>P.toolUseId===X);if(!q)this.applyBgStore(N4(this.bgStore(),{task_id:X,tool_use_id:X,task_type:"subagent",description:_.input?.description||"子 Agent",prompt:_.input?.prompt})),q=this.backgroundTasks.find((P)=>P.toolUseId===X);this.applyBgStore(V8(this.bgStore(),{task_id:q.id,status:W?"failed":"completed",summary:j})),this.onBackgroundTaskChanged(!0)}m1(this);return}uX(this,X,z,W,B)}),H("can_use_tool",(X)=>{iX(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)v(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: ${N(U)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((U)=>{K(`session "${this.sessionName}": mid-turn drain failed: ${N(U)}`)})}),H("bg_task_started",(X)=>{let z=X.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,W=z?this.nativeAgentTools.get(z):void 0;if(W)W.confirmed=!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(N4(this.bgStore(),{...X,tool_use_id:z})),this.onBackgroundTaskChanged(!0)}),H("bg_task_progress",(X)=>{this.applyBgStore(z3(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(W3(this.bgStore(),X)),this.onBackgroundTaskChanged(!!X.patch.status||X.patch.is_backgrounded===!0)}),H("bg_task_settled",(X)=>{if(K(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore(V8(this.bgStore(),X)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(B3(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 会话落盘确认失败: ${N(q)}`:null,P].filter(Boolean).join(";");if(D)v(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: ${N(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: ${N(q)}`)});let j=this.waitForTurnCloses().catch((q)=>{K(`session "${this.sessionName}": process-exit main-card close failed: ${N(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: ${N(P.reason)}`);if(!W)await E(this.chatId,`⚠️ ${G} 异常退出 (${B})。回复任意消息将重新启动。`)}).catch((q)=>{K(`session "${this.sessionName}": process-exit cleanup rejected: ${N(q)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?l7(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=d7(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 N8(Z)}contextLimitForDisplay($=this.proc){return T8($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;if(!await this.waitForTurnOpenSlot($,Z))return;if(this.currentTurn||this.openingTurn||this.pendingMidTurnMsgs.length===0)return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){K(`session "${this.sessionName}": mid-turn open ownership conflict: ${N(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(`
263
+
264
+ `),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)b0(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)b0(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 v(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${N(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 A0($,R.footer,this.footerElement(Z)):!0;y0($);let Q=await R0($,R1({suffix:Z}));if(Y&&Q){await J$($);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 v(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${V})。`)}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;this.bgResumePending=!1;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=C8({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 c(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 v(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let G;try{G=await G$(W)}catch(q){if(K(`session "${this.sessionName}": id_convert failed: ${q}`),J==="user_message"&&this.ownsTurnOpen($))await v(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let B=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return Z$(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,fileDeliveryMode:J==="user_message"&&this.pendingUserMessageCount===0?void 0:this.proc?this.procFileDeliveryModes.get(this.proc):void 0};if(Z$(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();return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&G9($.cardId)<MM)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(!W9(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),v(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),v(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=${G9(Z)}`);let H=C8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),X=await c(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 v(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let z;try{z=await G$(X)}catch(P){if(K(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${P}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await v(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}Z$(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)U0($.cardId,x1(this.taskBoard),{type:"insert_before",targetElementId:R.footer});if($.planLiveInserted)U0($.cardId,I4($.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=h2(z,h4(P.i,P.notice,D),{type:"insert_before",targetElementId:N0($)}).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(!f2(Z,P))continue;let T=$.assistantSegmentCount++,M=R.assistant(T);$.segmentTexts.set(M,D),await this.addCompletedAssistantSegment($,M,D)}mZ(this,Z,z,J,Y,$),await Q1(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(lH(Z).some((P)=>!j.has(P)))$.cardCapacityFailures.clear();await Q1(z);try{await gZ($,Z);let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await Q1(Z);let D=$.mathRendered?.get(Z);for(let[U,S]of _){if(G&&B&&U===G)continue;if(f2(Z,U))continue;if(D?.has(U))continue;await Q0(Z,U,this.completedAssistantElement(U,S))}let T=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",M=await A0(Z,R.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${T}`)),{notifyCardFailure:!1});y0(Z);let A=await R0(Z,R1({suffix:"\uD83D\uDCE8 转下一张"}));if(M&&A)await J$(Z);else K(`session "${this.sessionName}": rotate old-card terminal MISS footer=${M} settings=${A}`),await v(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++);U0(Z,l3($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:N0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=R.goalUpdate(Z.goalUpdateCount++);U0(Z.cardId,d3($,J),{type:"insert_before",targetElementId:N0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=R.goalUpdate($.goalUpdateCount++);U0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
265
+
266
+ 已清除`},{type:"insert_before",targetElementId:N0($)})}handleContextCompacted($){let Z=aW($);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<r6){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<r6||!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<r6){K(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let M=LM($);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=h2(U,h4(A,$,S),{type:"insert_before",targetElementId:N0(J)}).then((w)=>{if(C.cardId===U)C.created=w.landed,C.createFailure=w.failure;return w.landed}),J.contextCompactionPending.set(M,C),K(`session "${this.sessionName}": context compaction start #${A+1} key=${M}`),I2(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<r6){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:qM(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 _=PM(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([...aW(G?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,X,!1,B);let D=R.contextCompact(q),T=h4(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 w1(A,T,{type:"insert_before",targetElementId:N0(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 A0(A,D,T);else{if(uH(G.createFailure?.code,G.createFailure))dH(A,D),M=await A0(A,D,T,{notifyCardFailure:!1});if(!M)M=await w1(A,T,{type:"insert_before",targetElementId:N0(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: ${N(M)}`)}),I2(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>UM){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,U0(Z.cardId,I4(Z.planSteps,Z.planExplanation,R.planLive),{type:"insert_before",targetElementId:J})}else Q0(Z.cardId,R.planLive,I4(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&&S8(Z)===S8(J))return;let Y=this.currentTurn;if(Y){if(this.startWorkingFooter(Y),Y.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Y.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let 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);I2(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
265
267
 
266
268
  `).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 后台轮输出(未能建卡,纯文本兜底):
267
269
 
268
- ${J}`)}completedAssistantElement($,Z){if(NZ(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 PX(Y);if(!await O0(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=T0($),V=(async()=>{if(!await Y1(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(NZ(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 原始回复:
270
+ ${J}`)}completedAssistantElement($,Z){if(CZ(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 xX(Y);if(!await A0(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=N0($),V=(async()=>{if(!await w1(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(CZ(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 原始回复:
269
271
 
270
- ${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 eH($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return Z0($)}sendOutboundPath($,Z){let J=U6($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!HU(J)){K(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}K(`session "${this.sessionName}": outbound send from ${Z}: ${J}`);try{let Q=Y?.fileDeliveryMode??(this.proc?this.procFileDeliveryModes.get(this.proc):void 0)??this.getFileDeliveryMode();if(Y)Y.fileDeliveryMode=Q;if(Q==="chat"){Y?.outboundSentPaths.add(J),r4(this.chatId,J);return}if(!Y)throw Error("当前没有可关联的交付轮次");if(!Y.fileDelivery)Y.fileDelivery=this.createFileDeliveryForTurn(Y),this.fileDeliveries.add(Y.fileDelivery);Y.fileDelivery.add(J)}catch(Q){K(`session "${this.sessionName}": file delivery rejected: ${R(Q)}`),E(this.chatId,`❌ 文件交付失败:${R(Q)}`)}}createFileDeliveryForTurn($){return nz({chatId:this.chatId,managerOpenId:$.userOpenId,projectName:this.sessionName,createdAt:$.startedAt})}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}=t$(Date.now()-$.footerStatusStartedAt,t1()),H=Z===IW?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}=t$(Date.now()-$.footerStatusStartedAt,t1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(V)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,IW)}startWritingFooter($){this.startFooterStatus($,GU)}startWorkingFooter($){this.startFooterStatus($,KU)}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` | ${K6(V)}`}if($==="codex"){let V=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,H=V?await O8(()=>V.readRateLimits(),r0(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()?N2(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(R).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)k0(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,r0(Y)):this.currentTokenSource(),codexUsage:rQ(r0(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;if(await wZ(Y),Y.fileDelivery)try{for(let A of await Y.fileDelivery.finish())Y.outboundSentPaths.add(A)}catch(A){K(`session "${this.sessionName}": file delivery close failed: ${R(A)}`),await w(this.chatId,`❌ 文件交付收尾失败:${R(A)}`)}finally{this.fileDeliveries.delete(Y.fileDelivery)}this.stopFooterStatus(Y);let Q=(Date.now()-Y.startedAt)/1000,V=Y.cardId,H=Y.segmentTexts;await O$(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(y2(V,A)){X.set(A,M);continue}if(G?.has(A))continue;await J0(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",b=T5(A,M,S?0:void 0);if(b)_.push(`\uD83E\uDDE0 ${b}`);let v=$.lastTurnDelta?.costUsd??0;if(v>0)_.push(`\uD83D\uDCB0 $${v.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?E5($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",D=P?`${q}
271
- ${P}`:q,T=await O0(V,N.footer,this.footerElement(D));N0(V);let U=await D0(V,h$({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(T&&U)await v0(V);else{let A=`footer=${T?"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)C1(Y.messageId,[Y.userOpenId])}}});function V$($){return{card:{type:"raw",data:$}}}import{randomUUID as jU}from"node:crypto";function NJ($){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(r0($.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:y$().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 pW($,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(!qU.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(!LU.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&&!_$(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${jU()}`,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 LU,qU;var cW=O(()=>{_0();Y0();p0();LU=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"]),qU=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as PU}from"node:http";import{randomUUID as DU}from"node:crypto";function iW($){if($.allowReply&&$.buttons?.length)throw Error(dW);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:Z3($.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}`} · 回调失败:${Z0(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:Z0(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 _1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${Z0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:Z0(Z.response.text)});if(Y==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
272
- 你的下一条文字优先用于这条通知,完成后再回答 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'>${Z0(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:Z0(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 AU($){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(!MU.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>uW)return{error:`button "${Q}" text > ${uW} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=UU.has(H)?H:"default";J.push({id:Q,text:V,type:X})}return{buttons:J}}function OU($){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 nW($){try{let Z=PU((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:lW(J,Y)):lW(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 lW($,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
272
+ ${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 GX($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return Z0($)}sendOutboundPath($,Z){let J=U6($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!jM(J)){K(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}K(`session "${this.sessionName}": outbound send from ${Z}: ${J}`);try{let Q=Y?.fileDeliveryMode??(this.proc?this.procFileDeliveryModes.get(this.proc):void 0)??this.getFileDeliveryMode();if(Y)Y.fileDeliveryMode=Q;if(Q==="chat"){Y?.outboundSentPaths.add(J),X9(this.chatId,J);return}if(!Y)throw Error("当前没有可关联的交付轮次");if(!Y.fileDelivery)Y.fileDelivery=this.createFileDeliveryForTurn(Y),this.fileDeliveries.add(Y.fileDelivery);Y.fileDelivery.add(J)}catch(Q){K(`session "${this.sessionName}": file delivery rejected: ${N(Q)}`),E(this.chatId,`❌ 文件交付失败:${N(Q)}`)}}createFileDeliveryForTurn($){return QW({chatId:this.chatId,managerOpenId:$.userOpenId,projectName:this.sessionName,createdAt:$.startedAt})}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}=K2(Date.now()-$.footerStatusStartedAt,s6()),H=Z===oW?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}=K2(Date.now()-$.footerStatusStartedAt,s6());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(V)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,oW)}startWritingFooter($){this.startFooterStatus($,DM)}startWorkingFooter($){this.startFooterStatus($,FM)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Y,Q,V){if(J&&(!Y||!Y.enabled||Y.agent!==$))return" | 额度 MISS";if(Y?.agent===$&&Y.enabled&&($==="claude"||$==="dsh")){let H=await Y.readUsage();if(H.state==="ok"&&H.kind!=="balance"){let X=H.windows.find((W)=>W.kind==="fiveHour");if(Y.kind==="claude-subscription"){let W=zX(H,V),G={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(X??G,W??G)}let z=H.windows.find((W)=>W.kind==="weekly");if(X||z)return this.fmtDualWindowSuffix(X??null,z??null)}return` | ${i8(H)}`}if($==="codex"){let H=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,X=H?await U8(()=>H.readRateLimits(),a0(H)):null,z=H?X:Q;return z?.state==="ok"?this.fmtDualWindowSuffix(z.fiveHour??null,z.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()?N2(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(N).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)b0(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,a0(Y)):this.currentTokenSource(),codexUsage:eQ(a0(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;if(await gZ(Y),Y.fileDelivery)try{for(let A of await Y.fileDelivery.finish())Y.outboundSentPaths.add(A)}catch(A){K(`session "${this.sessionName}": file delivery close failed: ${N(A)}`),await v(this.chatId,`❌ 文件交付收尾失败:${N(A)}`)}finally{this.fileDeliveries.delete(Y.fileDelivery)}this.stopFooterStatus(Y);let Q=(Date.now()-Y.startedAt)/1000,V=Y.cardId,H=Y.segmentTexts;await Q1(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(f2(V,A)){X.set(A,U);continue}if(G?.has(A))continue;await Q0(V,A,this.completedAssistantElement(A,U))}if(Y.cardRotationFailed)for(let[A,U]of H)X.set(A,U);let B=Z?Z:"✅",_=[`${B} ⏱ ${F0(Q)}`];if(J.hasFreshResult){let{contextTokens:A,contextLimit:U}=$,S=Y.provider==="claude",C=c3(A,U,S?0:void 0);if(C)_.push(`\uD83E\uDDE0 ${C}`);let w=$.lastTurnDelta?.costUsd??0;if(w>0)_.push(`\uD83D\uDCB0 $${w.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?u3($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Y.model)):"",D=P?`${q}
273
+ ${P}`:q,T=await A0(V,R.footer,this.footerElement(D));y0(V);let M=await R0(V,R1({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(T&&M)await J$(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 v(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)k1(Y.messageId,[Y.userOpenId])}}});function Y$($){return{card:{type:"raw",data:$}}}import{randomUUID as AM}from"node:crypto";function bJ($){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(a0($.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 tW($,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(!RM.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(!OM.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&&!j$(H.provider))throw Error("invalid provider");return{event_id:`debug-model-${AM()}`,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 OM,RM;var eW=O(()=>{B0();Y0();m0();OM=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"]),RM=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as NM}from"node:http";import{randomUUID as TM}from"node:crypto";function YG($){if($.allowReply&&$.buttons?.length)throw Error(JG);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:Q3($.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}`} · 回调失败:${Z0(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:Z0(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:`通知:${Z0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:Z0(Z.response.text)});if(Y==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
274
+ 你的下一条文字优先用于这条通知,完成后再回答 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'>${Z0(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:Z0(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 CM($){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(!SM.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>$G)return{error:`button "${Q}" text > ${$G} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=xM.has(H)?H:"default";J.push({id:Q,text:V,type:X})}return{buttons:J}}function bM($){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 QG($){try{let Z=NM((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:ZG(J,Y)):ZG(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 ZG($,Z,J=J0){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
273
275
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
274
276
  `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
275
277
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
276
278
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
277
279
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
278
280
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
279
- `);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=I$(l);if(!F)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,NX(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}=AU(X.buttons);if(q)return Q(400,q);let{url:P,error:D}=OU(X.callback);if(D)return Q(400,D);let T=!!(j&&j.length);if(T&&z)return Q(400,dW);let U=T||z,A=P??"",M=FU.has(_)?_:"info",S=B||W,b=J.sanitizeSessionName(W),v=J.chatIdForSession(b);if(!v)return K(`notify: project "${W}" (sanitized "${b}") 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:[],g=[];for(let l of y){let F=String(l??"").trim();if(!F)continue;let C=await J.uploadImageKey(F);g.push({key:C??"",src:F})}let x=U?`nf_${DU()}`:"",I=iW({title:S,text:G,level:M,images:g,buttons:j,allowReply:z,notifyId:x}),p=await J.sendCard(v,I);if(!p)return K(`notify: sendCard failed → 502 (project="${W}" chat=${v.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(U&&x){let l={notifyId:x,callbackUrl:A,chatId:v,messageId:p,project:W,title:S,text:G,level:M,imageKeys:g,buttons:j,allowReply:z,createdAt:Date.now()};OX(l)}K(`notify: → ${W} (${v.slice(0,8)}…) level=${M} bytes=${G.length} images=${g.length} buttons=${j?.length??0} allowReply=${z} push=${U&&!!A?1:0} msg=${p}`),V(200,{ok:!0,chat_id:v,message_id:p,...x?{notify_id:x}:{}})}function e1($,Z){return iW({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var FU,UU,MU,uW=64,dW='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var r6=O(()=>{f();t();b0();A9();FU=new Set(["info","warn","error"]),UU=new Set(["default","primary","danger"]),MU=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as TJ,readFileSync as EJ,rmSync as RU}from"node:fs";import{homedir as s6}from"node:os";import{join as T$}from"node:path";function Y4($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[T$(s6(),".codex","skills"),T$(s6(),".claude","skills")];for(let Y of J){let Q=T$(Y,$.name,"SKILL.md");try{let V=TJ(Q)?EJ(Q,"utf8"):null;if(V===$.body)continue;I0(Q,$.body),K(`skill: ${V===null?"installed":"updated"} ${Q}`)}catch(V){K(`skill: sync failed (${Q}): ${V}`)}}if(!Z)NU($,D1)}function NU($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=T$(Z,".claude-plugin","plugin.json"),Y=T$(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)+`
280
- `;for(let[V,H]of[[J,Q],[Y,$.body]])try{let X=TJ(V)?EJ(V,"utf8"):null;if(X===H)continue;I0(V,H),K(`skill: ${X===null?"installed":"updated"} ${V}`)}catch(X){K(`skill: Claude plugin sync failed (${V}): ${X}`)}}function aW($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[T$(s6(),".codex","skills"),T$(s6(),".claude","skills")]).map((Q)=>T$(Q,$));if(!Z)Y.push(T$(D1,"skills",$));for(let Q of Y){let V=T$(Q,"SKILL.md");if(!TJ(V))continue;try{let H=EJ(V,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){K(`skill: obsolete path preserved because ownership is unclear ${V}`);continue}RU(Q,{recursive:!0,force:!1}),K(`skill: removed obsolete ${Q}`)}catch(H){K(`skill: obsolete removal failed (${Q}): ${H}`)}}}var t6=O(()=>{f();S0();V0()});function TU($){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`---
281
- name: ${oW}
281
+ `);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=w$(l);if(!F)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,fX(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}=CM(X.buttons);if(q)return Q(400,q);let{url:P,error:D}=bM(X.callback);if(D)return Q(400,D);let T=!!(j&&j.length);if(T&&z)return Q(400,JG);let M=T||z,A=P??"",U=EM.has(_)?_:"info",S=B||W,C=J.sanitizeSessionName(W),w=J.chatIdForSession(C);if(!w)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:[],g=[];for(let l of y){let F=String(l??"").trim();if(!F)continue;let b=await J.uploadImageKey(F);g.push({key:b??"",src:F})}let x=M?`nf_${TM()}`:"",I=YG({title:S,text:G,level:U,images:g,buttons:j,allowReply:z,notifyId:x}),p=await J.sendCard(w,I);if(!p)return K(`notify: sendCard failed → 502 (project="${W}" chat=${w.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(M&&x){let l={notifyId:x,callbackUrl:A,chatId:w,messageId:p,project:W,title:S,text:G,level:U,imageKeys:g,buttons:j,allowReply:z,createdAt:Date.now()};vX(l)}K(`notify: → ${W} (${w.slice(0,8)}…) level=${U} bytes=${G.length} images=${g.length} buttons=${j?.length??0} allowReply=${z} push=${M&&!!A?1:0} msg=${p}`),V(200,{ok:!0,chat_id:w,message_id:p,...x?{notify_id:x}:{}})}function o1($,Z){return YG({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var EM,xM,SM,$G=64,JG='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var t6=O(()=>{f();t();S0();U9();EM=new Set(["info","warn","error"]),xM=new Set(["default","primary","danger"]),SM=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as kJ,readFileSync as yJ,rmSync as kM}from"node:fs";import{homedir as e6}from"node:os";import{join as R$}from"node:path";function J4($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[R$(e6(),".codex","skills"),R$(e6(),".claude","skills")];for(let Y of J){let Q=R$(Y,$.name,"SKILL.md");try{let V=kJ(Q)?yJ(Q,"utf8"):null;if(V===$.body)continue;h0(Q,$.body),K(`skill: ${V===null?"installed":"updated"} ${Q}`)}catch(V){K(`skill: sync failed (${Q}): ${V}`)}}if(!Z)yM($,j1)}function yM($,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)+`
282
+ `;for(let[V,H]of[[J,Q],[Y,$.body]])try{let X=kJ(V)?yJ(V,"utf8"):null;if(X===H)continue;h0(V,H),K(`skill: ${X===null?"installed":"updated"} ${V}`)}catch(X){K(`skill: Claude plugin sync failed (${V}): ${X}`)}}function VG($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){K(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[R$(e6(),".codex","skills"),R$(e6(),".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(!kJ(V))continue;try{let H=yJ(V,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){K(`skill: obsolete path preserved because ownership is unclear ${V}`);continue}kM(Q,{recursive:!0,force:!1}),K(`skill: removed obsolete ${Q}`)}catch(H){K(`skill: obsolete removal failed (${Q}): ${H}`)}}}var $7=O(()=>{f();x0();V0()});function vM($){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`---
283
+ name: ${HG}
282
284
  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.")}
283
285
  ---
284
286
 
@@ -535,13 +537,13 @@ is the script's acknowledgement, distinct from the user's response.
535
537
  Hand-edits will be overwritten — set
536
538
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
537
539
  to maintain the file yourself.
538
- `}function rW(){Y4({name:oW,body:TU(h.notify.port)})}var oW="feishu-notify";var sW=O(()=>{y0();t6()});import{randomUUID as EU}from"node:crypto";function tW($){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(c2(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,_1(V,H,X),"回复送达状态未知"),await Q(V,V.messageId,e1(V,X),"回复送达状态未知")},async open(V,H,X){let z=I$(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=EZ(z.chatId);if(G.some((B)=>B.replyState?.status==="sending"||c2(B.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};D9(V);try{for(let j of G){let q={...j.replyState,status:"cancelled",cancelReason:"switched"};l2(j.notifyId,q),await Q(j,q.promptMessageId,_1(j,q),"已放弃上一条回复并切换通知")}let B={id:EU(),openId:X,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,_1(z,B));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};B.promptMessageId=_;try{l2(V,B)}catch(j){let q=`等待输入状态保存失败,未开始接收回复:${Z(j)}`;return await Q(z,_,_1(z,B,{status:"failed",detail:q}),q),{ok:!1,message:q,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{F9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,H,X,z){let W=I$(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 l2(V,_),$.onWaitingChanged(W.chatId),await Q(W,B.promptMessageId,_1(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(RX(H,z))return!0;let B=U9(H,X);if(!B?.replyState)return!1;let _=B.replyState;if(G>0&&G<_.openedAt)return!1;if(_.status!=="waiting"||c2(B.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:W,message_id:z,prompt_message_id:_.promptMessageId},q={..._,status:"sending",response:j};D9(B.notifyId);try{try{l2(B.notifyId,q)}catch(U){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(U)}`),!0}let P;try{if(await $.updateCard(_.promptMessageId,_1(B,q)),B.callbackUrl)P=await $.dispatch(B,j,X);else M9(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?A6(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{l2(B.notifyId,{...q,status:"failed",error:P.detail})}catch(U){let A=`${P.detail};失败状态保存失败:${Z(U)}`;try{xZ(B.notifyId,void 0,X,A)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}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,_1(B,q,D),T),await Q(B,B.messageId,e1(B,D),T),$.log(`notify-reply: notify_id=${B.notifyId} status=${D.status}`),!0}finally{F9(B.notifyId),$.onWaitingChanged(B.chatId)}}}}var eW=O(()=>{A9();r6()});class xJ{deps;tails=new Map;byRun=new Map;constructor($){this.deps=$}add($){return F$($.chatId,async()=>{let Z=this.tails.get($.chatId);if(Z){if(await this.deps.getChatTailMessageId($.chatId)===Z.messageId&&this.deps.getElementCount(Z.cardId)<xU){let Y=await this.deps.addElementResult(Z.cardId,j9($));if(Y.landed){this.attach(Z,$),await this.settings(Z);return}if(!$G(Y))throw ZG("agent card append",Y)}await this.seal(Z)}await this.create($)})}update($,Z=!1){return F$($.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,L9($.runId),j9($));if(!Q.landed){if(!$G(Q)||J.runs.size===1)throw ZG("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,L9($.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 F$($,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,KZ($));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:BZ([...$.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 $G($){return t4($.failure?.code,$.failure)}function ZG($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"})`:""}`)}var xU=50;var JG=O(()=>{Q$();v$();m3()});function YG($){let Z=SJ($,"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=Q4(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=HG(Z.prompt,'agent run requires "prompt"'),X=Q4(Z.effort);return{identityIds:Y,description:V4(Z.description),prompt:H,...X?{effort:X}:{},...V?{sessionId:V}:{}}}function QG($){let Z=SJ($,"agent follow-up request"),J=HG(Z.prompt,'agent follow-up requires "prompt"'),Y=Q4(Z.identity_id??Z.identityId),Q=Q4(Z.effort);return{description:V4(Z.description),prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function V4($){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 VG($){let Z=SJ($,"agent answer request"),J=Q4(Z.identity_id??Z.identityId),Y=Q4(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 SJ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function HG($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function Q4($){return(typeof $==="string"?$.trim():"")||void 0}function SU(){return["---",`name: ${XG}`,`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(`
539
- `)}function WG(){aW("lodestar-consult"),Y4({name:XG,body:SU()})}var XG="lodestar-agent",zG;var bJ=O(()=>{t6();zG=["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(`
540
- `)});function GG($){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}=f4({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,zG].filter(Boolean).join(`
540
+ `}function XG(){J4({name:HG,body:vM(h.notify.port)})}var HG="feishu-notify";var zG=O(()=>{k0();$7()});import{randomUUID as wM}from"node:crypto";function WG($){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(p2(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=w$(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=kZ(z.chatId);if(G.some((B)=>B.replyState?.status==="sending"||p2(B.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};P9(V);try{for(let j of G){let q={...j.replyState,status:"cancelled",cancelReason:"switched"};u2(j.notifyId,q),await Q(j,q.promptMessageId,W1(j,q),"已放弃上一条回复并切换通知")}let B={id:wM(),openId:X,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,W1(z,B));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};B.promptMessageId=_;try{u2(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{D9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,H,X,z){let W=w$(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 u2(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(wX(H,z))return!0;let B=F9(H,X);if(!B?.replyState)return!1;let _=B.replyState;if(G>0&&G<_.openedAt)return!1;if(_.status!=="waiting"||p2(B.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:W,message_id:z,prompt_message_id:_.promptMessageId},q={..._,status:"sending",response:j};P9(B.notifyId);try{try{u2(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 M9(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?O6(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{u2(B.notifyId,{...q,status:"failed",error:P.detail})}catch(M){let A=`${P.detail};失败状态保存失败:${Z(M)}`;try{yZ(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,o1(B,D),T),$.log(`notify-reply: notify_id=${B.notifyId} status=${D.status}`),!0}finally{D9(B.notifyId),$.onWaitingChanged(B.chatId)}}}}var GG=O(()=>{U9();t6()});function KG($){let Z=vJ($,"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=Y4(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=jG(Z.prompt,'agent run requires "prompt"'),X=Y4(Z.effort);return{identityIds:Y,description:Q4(Z.description),prompt:H,...X?{effort:X}:{},...V?{sessionId:V}:{}}}function BG($){let Z=vJ($,"agent follow-up request"),J=jG(Z.prompt,'agent follow-up requires "prompt"'),Y=Y4(Z.identity_id??Z.identityId),Q=Y4(Z.effort);return{description:Q4(Z.description),prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function Q4($){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 _G($){let Z=vJ($,"agent answer request"),J=Y4(Z.identity_id??Z.identityId),Y=Y4(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 vJ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function jG($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function Y4($){return(typeof $==="string"?$.trim():"")||void 0}function fM(){return["---",`name: ${LG}`,`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(`
541
+ `)}function PG(){VG("lodestar-consult"),J4({name:LG,body:fM()})}var LG="lodestar-agent",qG;var wJ=O(()=>{$7();qG=["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(`
542
+ `)});function DG($){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}=f4({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,qG].filter(Boolean).join(`
541
543
 
542
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return bU(Y,$.prompt,$.callbacks)}function bU($,Z,J={},Y=CY){let Q=[],V=null,H=!1,X=null,z=null,W=[],G,B,_=Date.now(),j=new Promise((F,C)=>{G=F,B=C}),q=(F)=>{if(!F)return null;try{return Y($.provider,F),J.onSession?.(F),null}catch(C){return C instanceof Error?C:Error(String(C))}},P=()=>{if($.off("assistant_text",T),$.off("tool_use",A),$.off("tool_result",M),$.off("subagent_step",S),$.off("can_use_tool",b),$.off("hook_callback",v),$.off("init",y),!$.isAlive())$.off("error",g);$.off("turn_retry",I),$.off("codex_account_changed",x),$.off("result",p),$.off("exit",l)},D=(F,C)=>{if(X)return X;return H=!0,W.length=0,X=Promise.resolve().then(async()=>{let d=q($.sessionId);try{await $.kill(3000)}catch(q1){z=q1 instanceof Error?q1:Error(String(q1))}P();let o=[F,d,z].filter((q1)=>!!q1),K0=o.length>1?AggregateError(o,o.map((q1)=>q1.message).join("; ")):o[0];if(K0){B(new E9(K0,Q.join("").trim(),$.sessionId));return}let G4=$.sessionId;if(!G4){B(new E9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let S9=Q.join("").trim(),J2=yU(C?.checkpoint,$);G({output:S9,outputTruncated:!1,sessionId:G4,...J2?{checkpointId:J2}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),X},T=(F)=>{if(H||F?.parentToolUseId||typeof F?.text!=="string")return;Q.push(F.text)},U=(F)=>{if(H)return;try{J.onProgress?.(F)}catch(C){D(C instanceof Error?C:Error(String(C)))}},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:""}),b=(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 C;try{C=CU(F)}catch(d){D(d instanceof Error?d:Error(String(d)));return}if(W.some((d)=>d.request.requestId===C.requestId))return;W.push({request:C,originalInput:F.input??{}});try{if(W.length===1)J.onNeedsInput?.(C)}catch(d){D(d instanceof Error?d:Error(String(d)))}},v=(F)=>{if(H)return;try{$.sendHookResponse(String(F.request_id),{})}catch(C){D(C instanceof Error?C:Error(String(C)))}},y=(F)=>{let C=q(F?.session_id??$.sessionId);if(C)D(C)},g=(F)=>{V=F instanceof Error?F:Error(String(F))},x=(F)=>{if(H)return;try{J.onCodexAccount?.(F.accountId)}catch(C){D(C instanceof Error?C:Error(String(C)))}if(F.diagnostics.length)U({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:F.diagnostics.join(";")})},I=(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}`})},p=(F)=>{let C=F?.is_error?Error(String(F.error??F.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(C,F)},l=(F)=>{if(H)return;let C=`code=${F?.code??"null"} signal=${F?.signal??"null"}`;D(V??Error(`delegated agent exited before result (${C})`))};$.on("assistant_text",T),$.on("tool_use",A),$.on("tool_result",M),$.on("subagent_step",S),$.on("can_use_tool",b),$.on("hook_callback",v),$.on("init",y),$.on("error",g),$.on("turn_retry",I),$.on("codex_account_changed",x),$.on("result",p),$.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,C){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:C}}),W.shift(),W[0])J.onNeedsInput?.(W[0].request)},async cancel(F="delegated agent cancelled"){let C=H;if(await D(Error(F)),await j.catch(()=>{}),C){if($.isAlive())await $.kill(3000);z=null,P()}if(z)throw z}}}function CU($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,V)=>kU(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 kU($,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 yU($,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 E9;var KG=O(()=>{w3();q4();Y0();bJ();E9=class E9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as wU,randomBytes as vU,randomUUID as fU}from"node:crypto";import{existsSync as hU,readdirSync as IU,readFileSync as MG}from"node:fs";import{join as e6}from"node:path";class yJ{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($=gU){this.deps=$;this.presentation=new xJ($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(_G);if(V4(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(_G);V4(J.description);let Y=this.requireMutableDescendant($,Z);if(!H4(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=DG(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=DG(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),this.readSnapshot(Y)}getRun($,Z){return this.readSnapshot(this.requireAccessibleRun($,Z))}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)));kJ(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($)));kJ([...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){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((_)=>mU(_,pU(_,Z.effort),J.resumeWorker?.sessionId)),z=`agent_${fU()}`,W={runId:z,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,description:V4(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,artifactsUnloaded:!1};try{await this.presentation.add(W)}catch(_){if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);let j=`Agent 卡片初始化失败,Agent 未启动: ${f0(_)}`;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",_),this.readSnapshot(G)}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: ${f0(q)}`)})}return this.readSnapshot(G)}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=vU(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:lU(C2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:D1},hostEnv:{LODESTAR_AGENT_URL:N8(h.notify.bind,h.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 E9){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=f0(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||x9(Z.status))return;if(Z.steps.push(J),Z.steps.length>LG)Z.steps.splice(0,Z.steps.length-LG);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: ${f0(Y)}`,K(`agent: terminal finalization failed run=${$.snapshot.runId}: ${f0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${f0(Y)}`).catch((Q)=>K(`agent: terminal failure delivery failed: ${f0(Q)}`))})}async cancelTree($,Z){let J=!H4($.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){kJ(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=AG(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: ${f0(H)}`)),V}let Q=[];for(let V of $.snapshot.workers)if(!x9(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: ${f0(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.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}: ${f0(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}): ${f0(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=wU("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=FG($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(e6(P1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;NG(Z),this.deps.writeTextArtifact(e6(P1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=FG($.snapshot);if($.artifactsUnloaded)OG(Z,Z.runId,this.deps.readTextArtifact);return 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!x9(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(!H4($.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&&(!H4(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=qG)throw Error(`Session has reached ${qG} active Agent runs`);if([...this.runs.values()].reduce((X,z)=>X+z.snapshot.workers.filter((W)=>!x9(W.status)||z.handles.get(W.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>PG)throw Error(`global Agent worker limit ${PG} 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),UG(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=BG.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=CJ||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=BG.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${CJ} 个 Agent)`),new Promise((Y)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Y}))}releaseSlot($){this.activeTurns--,UG(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<CJ;){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(!H4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!x9(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,artifactsUnloaded:!1,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.pruneRunArtifacts()}pruneRunArtifacts(){if(this.runs.size<=jG)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&H4(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0).sort((Z,J)=>Date.parse(Z.snapshot.finishedAt??Z.snapshot.createdAt)-Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt));for(let Z of $.slice(0,Math.max(0,$.length-jG))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function mU($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function pU($,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 DG($,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 H4($){return $==="completed"||$==="failed"||$==="cancelled"}function x9($){return $==="completed"||$==="failed"||$==="cancelled"}function FG($){return JSON.parse(JSON.stringify($))}function cU(){if(!hU(P1))return[];let $=[];for(let Z of IU(P1).filter((J)=>J.endsWith(".json")).sort()){let J=e6(P1,Z),Y;try{Y=JSON.parse(MG(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${f0(Q)}`)}if(!uU(Y))throw Error(`agent run artifact is invalid: ${J}`);OG(Y,J),$.push(Y)}return $}function uU($){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 AG($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(f0).join("; ")}`)}function kJ($){if($.some((Z)=>Z.status==="rejected"))throw AG($)}function f0($){return $ instanceof Error?$.message:String($)}function lU($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function OG($,Z,J=RG){if($.promptArtifact)$.prompt=J($.promptArtifact,`prompt for ${Z}`);for(let Y of $.workers)if(Y.outputArtifact)Y.output=J(Y.outputArtifact,`output for ${Z}`)}function RG($,Z){NG($);try{return MG(e6(P1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${f0(J)}`)}}function NG($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function UG($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var CJ=8,BG,_G="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",jG=512,LG=50,qG=64,PG=128,gU;var TG=O(()=>{v$();JG();t();y0();f6();KG();V0();S0();f();BG=new Map([["openrouter",2]]),gU={getCatalog:a1,startWorker:GG,sendCard:c,getChatTailMessageId:q5,sendTextRaw:w,convertMessageToCard:J$,recordCardCreated:d0,getElementCount:e4,addElementResult:w2,replaceElementResult:fV,deleteElementChecked:hV,cancelSummary:N0,patchSettingsChecked:D0,dispose:v0,writeArtifact:s,writeTextArtifact:I0,readTextArtifact:RG,loadArtifacts:cU}});async function SG($,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=nU($.headers.authorization);if(!V)return Q(401,{error:"missing bearer capability"});let H=dU(Y,V);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await A2(),Q(200,aU(a1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,YG(await wJ($)));return Q(202,$7(G))}catch(G){return Q(409,{error:xG(G)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let z=iU(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,$7(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,QG(await wJ($)));return Q(202,$7(G))}if(W==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,z,VG(await wJ($)));return Q(200,$7(G))}}catch(G){return Q(409,{error:xG(G)})}return Q(405,{error:"unsupported agent endpoint"})}function dU($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function iU($){try{return decodeURIComponent($)}catch{return null}}function nU($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function wJ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>EG)throw Error(`request body exceeds ${EG} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function aU($){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 $7($){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 xG($){return $ instanceof Error?$.message:String($)}var EG=4194304;var bG=O(()=>{f6();Y0()});function CG($){Y4({name:sz,body:ZW()},$)}var kG=O(()=>{t6();c6()});import{chmodSync as oU,existsSync as vJ,readFileSync as vG,realpathSync as rU,unlinkSync as sU}from"node:fs";import{homedir as tU}from"node:os";import{basename as eU,dirname as $M,join as j1,resolve as ZM}from"node:path";function JM($={}){let Z=rU(ZM($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??vJ,Q=$M(Z),V=j1(Q,"src","agent-cli.ts"),H=j1(Q,"lodestar-agent.js"),X=j1(Q,"dist","lodestar-agent.js"),W=/^bun(?:\.exe)?$/i.test(eU(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 fG($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??QM(Z,$.homeDir??tU(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??JM(),V=j1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${wG(Q.runtime)}" "${wG(Q.entry)}" %*\r
544
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return hM(Y,$.prompt,$.callbacks)}function hM($,Z,J={},Y=wY){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",w),$.off("init",y),!$.isAlive())$.off("error",g);$.off("turn_retry",I),$.off("codex_account_changed",x),$.off("result",p),$.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),G0=o.length>1?AggregateError(o,o.map((B1)=>B1.message).join("; ")):o[0];if(G0){B(new N9(G0,Q.join("").trim(),$.sessionId));return}let W4=$.sessionId;if(!W4){B(new N9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let E9=Q.join("").trim(),t1=mM(b?.checkpoint,$);G({output:E9,outputTruncated:!1,sessionId:W4,...t1?{checkpointId:t1}:{},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=IM(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)))}},w=(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)},g=(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)M({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:F.diagnostics.join(";")})},I=(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}`})},p=(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",w),$.on("init",y),$.on("error",g),$.on("turn_retry",I),$.on("codex_account_changed",x),$.on("result",p),$.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 IM($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,V)=>gM(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 gM($,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 mM($,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 N9;var FG=O(()=>{f3();L4();Y0();wJ();N9=class N9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as pM,randomBytes as cM,randomUUID as uM}from"node:crypto";import{existsSync as lM,readdirSync as dM,readFileSync as SG}from"node:fs";import{join as Z7}from"node:path";class IJ{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($=iM){this.deps=$;this.presentation=new B9($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(UG);if(Q4(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(UG);Q4(J.description);let Y=this.requireMutableDescendant($,Z);if(!V4(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=TG(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=TG(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),this.readSnapshot(Y)}getRun($,Z){return this.readSnapshot(this.requireAccessibleRun($,Z))}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)));hJ(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($)));hJ([...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){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((_)=>nM(_,aM(_,Z.effort),J.resumeWorker?.sessionId)),z=`agent_${uM()}`,W={runId:z,codexAccountId:Q,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,description:Q4(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,artifactsUnloaded:!1};try{await this.presentation.add(W)}catch(_){if(this.runs.set(z,G),J.parentRunId)Y?.children.add(z);let j=`Agent 卡片初始化失败,Agent 未启动: ${w0(_)}`;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",_),this.readSnapshot(G)}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: ${w0(q)}`)})}return this.readSnapshot(G)}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=cM(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:sM(y2($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:j1},hostEnv:{LODESTAR_AGENT_URL:O8(h.notify.bind,h.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 N9){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=w0(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||T9(Z.status))return;if(Z.steps.push(J),Z.steps.length>OG)Z.steps.splice(0,Z.steps.length-OG);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: ${w0(Y)}`,K(`agent: terminal finalization failed run=${$.snapshot.runId}: ${w0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${w0(Y)}`).catch((Q)=>K(`agent: terminal failure delivery failed: ${w0(Q)}`))})}async cancelTree($,Z){let J=!V4($.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){hJ(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=CG(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: ${w0(H)}`)),V}let Q=[];for(let V of $.snapshot.workers)if(!T9(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: ${w0(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.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}: ${w0(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}): ${w0(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=pM("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=EG($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(Z7(_1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;yG(Z),this.deps.writeTextArtifact(Z7(_1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=EG($.snapshot);if($.artifactsUnloaded)bG(Z,Z.runId,this.deps.readTextArtifact);return 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!T9(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(!V4($.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&&(!V4(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=RG)throw Error(`Session has reached ${RG} active Agent runs`);if([...this.runs.values()].reduce((X,z)=>X+z.snapshot.workers.filter((W)=>!T9(W.status)||z.handles.get(W.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>NG)throw Error(`global Agent worker limit ${NG} 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),xG(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=MG.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=fJ||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=MG.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${fJ} 个 Agent)`),new Promise((Y)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Y}))}releaseSlot($){this.activeTurns--,xG(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<fJ;){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(!V4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!T9(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,artifactsUnloaded:!1,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.pruneRunArtifacts()}pruneRunArtifacts(){if(this.runs.size<=AG)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&V4(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0).sort((Z,J)=>Date.parse(Z.snapshot.finishedAt??Z.snapshot.createdAt)-Date.parse(J.snapshot.finishedAt??J.snapshot.createdAt));for(let Z of $.slice(0,Math.max(0,$.length-AG))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function nM($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function aM($,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 TG($,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 V4($){return $==="completed"||$==="failed"||$==="cancelled"}function T9($){return $==="completed"||$==="failed"||$==="cancelled"}function EG($){return JSON.parse(JSON.stringify($))}function oM(){if(!lM(_1))return[];let $=[];for(let Z of dM(_1).filter((J)=>J.endsWith(".json")).sort()){let J=Z7(_1,Z),Y;try{Y=JSON.parse(SG(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${w0(Q)}`)}if(!rM(Y))throw Error(`agent run artifact is invalid: ${J}`);bG(Y,J),$.push(Y)}return $}function rM($){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 CG($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(w0).join("; ")}`)}function hJ($){if($.some((Z)=>Z.status==="rejected"))throw CG($)}function w0($){return $ instanceof Error?$.message:String($)}function sM($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function bG($,Z,J=kG){if($.promptArtifact)$.prompt=J($.promptArtifact,`prompt for ${Z}`);for(let Y of $.workers)if(Y.outputArtifact)Y.output=J(Y.outputArtifact,`output for ${Z}`)}function kG($,Z){yG($);try{return SG(Z7(_1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${w0(J)}`)}}function yG($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function xG($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var fJ=8,MG,UG="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",AG=512,OG=50,RG=64,NG=128,iM;var vG=O(()=>{PZ();FZ();t();k0();h6();FG();V0();x0();f();MG=new Map([["openrouter",2]]),iM={...DZ,getCatalog:d1,startWorker:DG,sendTextRaw:v,writeArtifact:s,writeTextArtifact:h0,readTextArtifact:kG,loadArtifacts:oM}});async function hG($,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=$U($.headers.authorization);if(!V)return Q(401,{error:"missing bearer capability"});let H=tM(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,ZU(d1(H.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,KG(await gJ($)));return Q(202,J7(G))}catch(G){return Q(409,{error:fG(G)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let z=eM(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,J7(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,BG(await gJ($)));return Q(202,J7(G))}if(W==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,z,_G(await gJ($)));return Q(200,J7(G))}}catch(G){return Q(409,{error:fG(G)})}return Q(405,{error:"unsupported agent endpoint"})}function tM($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function eM($){try{return decodeURIComponent($)}catch{return null}}function $U($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function gJ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>wG)throw Error(`request body exceeds ${wG} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function ZU($){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 J7($){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 fG($){return $ instanceof Error?$.message:String($)}var wG=4194304;var IG=O(()=>{h6();Y0()});function gG($){J4({name:zW,body:BW()},$)}var mG=O(()=>{$7();u6()});import{chmodSync as JU,existsSync as mJ,readFileSync as uG,realpathSync as YU,unlinkSync as QU}from"node:fs";import{homedir as VU}from"node:os";import{basename as HU,dirname as XU,join as G1,resolve as zU}from"node:path";function WU($={}){let Z=YU(zU($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??mJ,Q=XU(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(HU(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 lG($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??KU(Z,$.homeDir??VU(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??WU(),V=G1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${cG(Q.runtime)}" "${cG(Q.entry)}" %*\r
543
545
  `:`#!/bin/sh
544
- exec ${yG(Q.runtime)} ${yG(Q.entry)} "$@"
545
- `,X=vJ(V)?vG(V,"utf8"):null;if(X!==H)_Y(V,H),K(`command: ${X===null?"installed":"updated"} ${V}`);else oU(V,448);return VM(J,Y,Z),YM(Y,Z),V}function YM($,Z){let J=j1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!vJ(J))return;try{let Y=vG(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){K(`command: obsolete path preserved because ownership is unclear ${J}`);return}sU(J),K(`command: removed obsolete ${J}`)}catch(Y){K(`command: obsolete removal failed (${J}): ${Y}`)}}function QM($,Z,J){if($==="win32")return j1(J??j1(Z,"AppData","Local"),"Lodestar","bin");return j1(Z,".local","bin")}function VM($,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 yG($){return`'${$.replaceAll("'",`'"'"'`)}'`}function wG($){return $.replaceAll('"','""')}var hG=O(()=>{f();S0()});function IG($,Z,J){return $>0&&Z-$>J}async function gG($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function mG($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function fJ($){return typeof $==="string"&&$.length>0?$:void 0}function pG($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=fJ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=fJ(J.file_key);if(!Y)return null;let Q=fJ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function cG($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function uG($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class hJ{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 c$($){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 dG($){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(j0(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=c$(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=c$(z);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${W}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(B){let _=c$(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 _=c$(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 _=c$(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=c$(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=c$(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=c$(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=c$(W);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var iG=O(()=>{A1()});var xM={};import*as z4 from"@larksuiteoapi/node-sdk";import{chmodSync as HM,existsSync as gJ,mkdirSync as XM,readFileSync as zM,unlinkSync as J7,writeFileSync as WM}from"node:fs";import{dirname as GM}from"node:path";function W4($,Z){if(L1=Math.max(L1,Z),Z7)return Z7;a0=!0,oG?.(),i$.close();try{rG?.()}catch(J){L1=1,K(`shutdown WebSocket close failed: ${J}`)}try{Z2.persist()}catch(J){K(`shutdown alive marker write failed: ${J}`),L1=1}return Z7=(async()=>{K(`${$}: staged shutdown begin sessions=${d$.size}`);try{let J=(async()=>{await uG(()=>[...i$.pending(),...tG]),Z2.freezeForShutdown();let H=await Promise.allSettled([mJ.shutdown(`daemon ${$}`),l1.shutdown()]),X=await Promise.allSettled([hZ()]),z=await Promise.allSettled([...d$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[...H,...X,...z]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),aG)}),V=await Promise.race([J.then((H)=>{for(let X of H)if(X.status==="rejected")L1=1,K(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(V==="deadline")L1=1,K(`${$}: shutdown deadline ${aG}ms reached; forcing exit`);else K(`${$}: all sessions stopped`)}catch(J){K(`${$}: staged shutdown failed: ${J}`),L1=1}finally{sG(),process.exit(L1)}})(),Z7}function pJ($){return cG(tG,$)}function eG($,Z="ws"){if(a0)return K(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=BM.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 _M(){Z2.persist()}function $K($,Z){return cJ.sessionFor($,Z)}async function jM($){return await cJ.createTempSession($)}async function LM($,Z){return await cJ.disbandTempSession($,Z)}function qM($){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(`
546
+ exec ${pG(Q.runtime)} ${pG(Q.entry)} "$@"
547
+ `,X=mJ(V)?uG(V,"utf8"):null;if(X!==H)PY(V,H),K(`command: ${X===null?"installed":"updated"} ${V}`);else JU(V,448);return BU(J,Y,Z),GU(Y,Z),V}function GU($,Z){let J=G1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!mJ(J))return;try{let Y=uG(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){K(`command: obsolete path preserved because ownership is unclear ${J}`);return}QU(J),K(`command: removed obsolete ${J}`)}catch(Y){K(`command: obsolete removal failed (${J}): ${Y}`)}}function KU($,Z,J){if($==="win32")return G1(J??G1(Z,"AppData","Local"),"Lodestar","bin");return G1(Z,".local","bin")}function BU($,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 pG($){return`'${$.replaceAll("'",`'"'"'`)}'`}function cG($){return $.replaceAll('"','""')}var dG=O(()=>{f();x0()});function iG($,Z,J){return $>0&&Z-$>J}async function nG($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function aG($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function pJ($){return typeof $==="string"&&$.length>0?$:void 0}function oG($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=pJ(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=pJ(J.file_key);if(!Y)return null;let Q=pJ(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function rG($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function sG($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class cJ{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 tG($,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 eG($){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=tG(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=tG(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 $K=O(()=>{D1()});var wU={};import*as X4 from"@larksuiteoapi/node-sdk";import{chmodSync as _U,existsSync as lJ,mkdirSync as jU,readFileSync as LU,unlinkSync as Q7,writeFileSync as qU}from"node:fs";import{dirname as PU}from"node:path";function z4($,Z){if(K1=Math.max(K1,Z),Y7)return Y7;i0=!0,YK?.(),u$.close();try{QK?.()}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 Y7=(async()=>{K(`${$}: staged shutdown begin sessions=${c$.size}`);try{let J=(async()=>{await sG(()=>[...u$.pending(),...HK]),s1.freezeForShutdown();let H=await Promise.allSettled([V7.shutdown(`daemon ${$}`),p1.shutdown()]),X=await Promise.allSettled([cZ()]),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"),JK)}),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 ${JK}ms reached; forcing exit`);else K(`${$}: all sessions stopped`)}catch(J){K(`${$}: staged shutdown failed: ${J}`),K1=1}finally{VK(),process.exit(K1)}})(),Y7}function dJ($){return rG(HK,$)}function XK($,Z="ws"){if(i0)return K(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=FU.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 MU(){s1.persist()}function zK($,Z){return iJ.sessionFor($,Z)}async function UU($){return await iJ.createTempSession($)}async function AU($,Z){return await iJ.disbandTempSession($,Z)}function OU($){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(`
546
548
 
547
- `),imageKeys:Z,fileKeys:J}}async function DM($,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&&X4.has(V))return;if(V){if(X4.add(V),X4.size>200){let A=[...X4];X4.clear();for(let M of A.slice(-100))X4.add(M)}}let H=Number(J.create_time??0);if(IG(H,Z,PM)){if(K(`drop stale message ${V} ageAtReceipt=${Math.round((Z-H)/1000)}s`),V)l0(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{WM(y9,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=P0.get(X);if(!G)await a4(),G=P0.get(X);if(!G)G=await L5(X)??void 0;if(!G){K(`unknown chat ${X}, dropping message`),await E(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let B=F5(G);b2(B,X);let _=$K(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=qM(j);D=A.imageKeys.length>0||A.fileKeys.length>0,P=A.markdown.trim();for(let M of A.imageKeys){let S=await o4(J.message_id,M,"image");if(S)T.push(S)}for(let M of A.fileKeys){let S=await o4(J.message_id,M.key,"file",M.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:()=>Y7.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=pG(q,j);if(U){let A=await o4(J.message_id,U.key,U.type,U.name);if(!A){await E(X,mG(q));return}if(T.push(A),!P&&U.displayText)P=U.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 Q7($){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 FM($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function z0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function l$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function u$($){return z0($.card?V$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function $2($,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 UM($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=Q7(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=FM(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&V)try{await A$(V,H);return}catch(j){K(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await $2(Q,`⚠️ ${Y}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await $2(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 $2(Q,`${B?"❌":"✅"} ${Y}: ${W}`)}async function MM($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await $2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${Q7(J)}失败: ${Y}`)}function ZK($){return AM.accept($)}async function OM($){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=I$(H);if(X)$.__cardActionChatId=X.chatId;if(J.kind==="notify_callback")return await RM(J,Y,Q);let z=J.kind==="notify_reply"?await Y7.open(H,Y,Q):await Y7.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?l$(X,W):W}let V=d$.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(V$(z1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let z=X instanceof Error?X.message:String(X);return z0(V$(z1({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 u$(H)}case"model_page":{let H=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return u$(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 u$(await(J.mode==="add"?V.onModelAddOpen(H,X):V.onProviderSelect(X,H)))}case"model_add":case"model_remove":case"model_custom_remove":return u$(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 u$(H)}case"model_custom_prompt":{let H=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return u$(H)}case"model_panel_cancel":{let H=await V.onModelPanelCancel(String(J.panel_id??""));return u$(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 u$(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(V$(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}}:V$(z1({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}}:V$(z1({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(V$(QZ({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await V.onTasklistEnable();return z0(V$(H.card),H.ok)}case"tasklist_delete_prompt":{let H=V.onTasklistDeletePrompt(String(J.guid??""));return z0(V$(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await V.onTasklistDeleteConfirm(String(J.guid??""));return z0(V$(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => ($J(),eZ));return await H(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return u$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function RM($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=I$(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 l$(V,z0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return l$(V,{toast:{type:"info",content:"已处理过"}});if(c2(Y))return l$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return l$(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}"`),l$(V,z0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{M9(V.notifyId,H.id,J)}catch(W){return l$(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)`),l$(V,{...V$(e1(V,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}D9(V.notifyId);let X=pJ(NM(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 l$(V,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:z})}async function NM($,Z,J){try{let Y=e1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await A$($.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 SZ($,Z,J),V=Q.ok?"complete":"retry",H;if(Q.ok){let X=A6($.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 $2($.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=e1($,H);await A$($.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 $2($.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{F9($.notifyId)}}function IJ($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function TM(){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(gJ(F1))J7(F1)}catch{}try{Bun.serve({unix:F1,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(a0)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(!gJ(y9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(zM(y9,"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=d$.get(Q.chat_id);return G?Response.json(NJ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=d$.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=pW(Y,Q,j.data?.items?.[0],h.feishu.app_id,_.messageId);K(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let P=ZK(q);return await i$.enqueue(Q.chat_id,async()=>{}),Response.json({admission:P,state:NJ(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}`),!eG(W,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Y.wait_for_handling===!0)await i$.enqueue(Q.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{HM(F1,384)}catch{}K(`debug: inject socket listening at ${F1}`)}catch($){K(`debug: socket bind failed: ${$}`)}}async function EM(){K(`lodestar-daemon: pid ${process.pid} starting`),Z2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (sZ(),Wz));if(a0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Y0(),dQ));if(a0)return;if(await Z(),a0)return;if(r3(),e3(),$5(),J5(),V5(),await a4(),a0)return;setInterval(()=>{a4()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (WJ(),zJ));if(a0)return;try{await J()}catch(F){K(`tasklist deletion reconcile failed: ${F instanceof Error?F.message:F}`)}if(a0)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,C=0,d=!1)=>{if(a0)return;let o=Date.now()+C;if(_){if(P||=d,o>=j){K(`[ws] rebuild already scheduled — ${F}`);return}clearTimeout(_)}j=o,q=F,P=d,_=setTimeout(()=>{let K0=q,G4=P;_=null,j=0,q="",P=!1,D(K0,G4)},C)},U={error:(F)=>K(`[ws-sdk error] ${IJ(F)}`),warn:(F)=>{let C=IJ(F);if(K(`[ws-sdk warn] ${C}`),C.includes("no pong/inbound"))T("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(F)=>K(`[ws-sdk] ${IJ(F)}`),debug:(F)=>{},trace:(F)=>{}},A=new z4.EventDispatcher({}),M=()=>{if(Q=Date.now(),V=0,X)clearTimeout(X),X=null};A.register({"im.message.receive_v1":async(F)=>{if(M(),!eG(F))throw Error("daemon shutdown in progress")}}),A.register({"card.action.trigger":async(F)=>{return M(),ZK(F)}});let S=()=>new z4.WSClient({appId:h.feishu.app_id,appSecret:h.feishu.app_secret,loggerLevel:z4.LoggerLevel.info,logger:U,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>K("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>v(),onError:(F)=>D(`SDK onError: ${F?.message??F}`)});D=(F,C=!1)=>{if(a0)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,C)}),H=!1,C)b()};let b=()=>{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)},v=()=>{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,g=2,x=0,I=setInterval(()=>{if(a0)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}/${g})`),x>=g)x=0,D(`watchdog: stuck in '${F}' ~${Math.round(y*g/1000)}s`)},y);rG=()=>{if(clearInterval(I),_)clearTimeout(_);if(X)clearTimeout(X);Y.close({force:!0})};let p=AX();nW({bind:h.notify.bind,port:h.notify.port,extraHandler:(F,C,d)=>SG(F,C,d,{service:mJ,authorizeSession:(o)=>{for(let K0 of d$.values())if(K0.acceptsAgentCapability(o))return K0;return null}})}),fG(),rW(),WG(),CG();let l=Z2.enqueue();oG=AY(K,{enabled:h.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 ${P0.size} groups`),TM();for(let F of p)pJ(i$.enqueue(F.chatId,()=>Y7.recover(F))).catch((C)=>K(`notify-reply recovery failed: ${C instanceof Error?C.message:C}`));await l}var nG=!1,a0=!1,Z7=null,L1=0,oG,rG,aG=15000,sG=()=>{if(nG)return;nG=!0;try{Z2.persist()}catch($){K(`alive marker write failed: ${$}`)}try{J7(o0)}catch{}try{J7(F1)}catch{}},d$,mJ,i$,Z2,KM,tG,BM,cJ,PM=30000,X4,Y7,AM;var JK=O(()=>{VJ();t();Q$();cW();A9();r6();r6();sW();eW();TG();fZ();x6();bG();bJ();kG();hG();y0();f();H2();V0();L7();g3();iG();{let $=w9(o0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(gJ(o0))try{J7(o0)}catch{}}XM(GM(o0),{recursive:!0});eJ(o0);process.on("exit",sG);process.on("SIGTERM",()=>{W4("SIGTERM",0)});process.on("SIGINT",()=>{W4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{W4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{K(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),W4("unhandledRejection",1)});process.on("uncaughtException",($)=>{K(`uncaughtException: ${$.stack??$.message}`),W4("uncaughtException",1)});d$=new Map,mJ=new yJ,i$=new m4,Z2=new hJ({readMarker:G5,writeMarker:W5,sessions:()=>d$.values(),chatIdForSession:v8,sessionFor:$K,actor:i$,isShuttingDown:()=>a0,log:K}),KM=new I3(30000),tG=new Set,BM=YV({actor:i$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>DM($,Z)});cJ=dG({registry:d$,createSession:($,Z)=>{let J=new K$($,Z,{onLifecycleChange:_M,onCreateTempSession:jM,onDisbandTempSession:LM,onCancelAgentRuns:(Y,Q,V)=>mJ.cancelSessionRuns(Y,Q,V)});return Z2.transferPending(J),J},ensureChatForSession:B5,disbandChatForSessionExact:j5,chatIdForSession:v8,clearSessionConversationState:z5,registerTempSessionLease:s3,hasTempSessionLease:t3,replaceTurnAnchors:$$,runExclusive:($,Z)=>i$.enqueue($,Z),log:K});X4=new Set,Y7=tW({sendCard:c,updateCard:A$,sendText:E,dispatch:SZ,onWaitingChanged:($)=>d$.get($)?.refreshPendingAsks(),log:K});AM=QV({actor:i$,deduper:KM,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=I$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:OM,present:UM,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await MM($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await $2(String($?.context?.open_chat_id??""),`⚠️ ${Q7(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:($)=>{pJ($)},onBackgroundError:($)=>{K(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${Q7(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}})}});EM().catch(($)=>{K(`boot fatal: ${$}`),W4("boot fatal",1)})});V0();L7();import{existsSync as YK,unlinkSync as SM}from"node:fs";var B$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function bM(){if(!YK(x0)){if(process.stdin.isTTY){console.log(),console.log(`${B$.bold}${B$.yellow}Lodestar: 未找到配置, 启动安装向导...${B$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (xY(),EY));await Z();return}console.error(`${B$.red}Lodestar: 未找到配置 ${x0}${B$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${B$.green}lodestar-setup${B$.reset} 完成首次配置 (或直接运行 ${B$.green}lodestar-daemon${B$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=w9(o0);if($.state==="exit")console.error(`${B$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${B$.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(` • 误判 / 已经死了: 手删 ${o0} 后再跑`),process.exit(1);if(YK(o0))try{SM(o0)}catch{}await Promise.resolve().then(() => (JK(),xM))}bM().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
549
+ `),imageKeys:Z,fileKeys:J}}async function NU($,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&&H4.has(V))return;if(V){if(H4.add(V),H4.size>200){let A=[...H4];H4.clear();for(let U of A.slice(-100))H4.add(U)}}let H=Number(J.create_time??0);if(iG(H,Z,RU)){if(K(`drop stale message ${V} ageAtReceipt=${Math.round((Z-H)/1000)}s`),V)u0(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{qU(b9,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 V9(),G=q0.get(X);if(!G)G=await KZ(X)??void 0;if(!G){K(`unknown chat ${X}, dropping message`),await E(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let B=LZ(G);k2(B,X);let _=zK(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=OU(j);D=A.imageKeys.length>0||A.fileKeys.length>0,P=A.markdown.trim();for(let U of A.imageKeys){let S=await H9(J.message_id,U,"image");if(S)T.push(S)}for(let U of A.fileKeys){let S=await H9(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 nG({reply:()=>H7.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=oG(q,j);if(M){let A=await H9(J.message_id,M.key,M.type,M.name);if(!A){await E(X,aG(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 X7($){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 TU($){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 v($,Z))K(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function EU($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=X7(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=TU(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&V)try{await w2(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 xU($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await r1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${X7(J)}失败: ${Y}`)}function WK($){return SU.accept($)}async function CU($){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=w$(H);if(X)$.__cardActionChatId=X.chatId;if(J.kind==="notify_callback")return await bU(J,Y,Q);let z=J.kind==="notify_reply"?await H7.open(H,Y,Q):await H7.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$($1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let z=X instanceof Error?X.message:String(X);return z0(Y$($1({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$($1({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$($1({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$(M5({...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(() => (VJ(),QJ));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 bU($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=w$(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(p2(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{M9(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}))})}P9(V.notifyId);let X=dJ(kU(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 kU($,Z,J){try{let Y=o1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await w2($.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 vZ($,Z,J),V=Q.ok?"complete":"retry",H;if(Q.ok){let X=O6($.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 w2($.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{D9($.notifyId)}}function uJ($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function yU(){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(lJ(L1))Q7(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(!lJ(b9))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(LU(b9,"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(bJ(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 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=tW(Y,Q,j.data?.items?.[0],h.feishu.app_id,_.messageId);K(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let P=WK(q);return await u$.enqueue(Q.chat_id,async()=>{}),Response.json({admission:P,state:bJ(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}`),!XK(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{_U(L1,384)}catch{}K(`debug: inject socket listening at ${L1}`)}catch($){K(`debug: socket bind failed: ${$}`)}}async function vU(){K(`lodestar-daemon: pid ${process.pid} starting`),s1.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (JJ(),Mz));if(i0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Y0(),aQ));if(i0)return;if(await Z(),i0)return;if(i5(),o5(),r5(),t5(),ZZ(),await V9(),i0)return;setInterval(()=>{V9()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (jJ(),_J));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 G0=q,W4=P;_=null,j=0,q="",P=!1,D(G0,W4)},b)},M={error:(F)=>K(`[ws-sdk error] ${uJ(F)}`),warn:(F)=>{let b=uJ(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] ${uJ(F)}`),debug:(F)=>{},trace:(F)=>{}},A=new X4.EventDispatcher({}),U=()=>{if(Q=Date.now(),V=0,X)clearTimeout(X),X=null};A.register({"im.message.receive_v1":async(F)=>{if(U(),!XK(F))throw Error("daemon shutdown in progress")}}),A.register({"card.action.trigger":async(F)=>{return U(),WK(F)}});let S=()=>new X4.WSClient({appId:h.feishu.app_id,appSecret:h.feishu.app_secret,loggerLevel:X4.LoggerLevel.info,logger:M,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>K("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>w(),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)},w=()=>{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,g=2,x=0,I=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}/${g})`),x>=g)x=0,D(`watchdog: stuck in '${F}' ~${Math.round(y*g/1000)}s`)},y);QK=()=>{if(clearInterval(I),_)clearTimeout(_);if(X)clearTimeout(X);Y.close({force:!0})};let p=yX();QG({bind:h.notify.bind,port:h.notify.port,extraHandler:(F,b,d)=>hG(F,b,d,{service:V7,authorizeSession:(o)=>{for(let G0 of c$.values())if(G0.acceptsAgentCapability(o))return G0;return null}})}),lG(),XG(),PG(),gG();let l=s1.enqueue();YK=TY(K,{enabled:h.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`),yU();for(let F of p)dJ(u$.enqueue(F.chatId,()=>H7.recover(F))).catch((b)=>K(`notify-reply recovery failed: ${b instanceof Error?b.message:b}`));await l}var ZK=!1,i0=!1,Y7=null,K1=0,YK,QK,JK=15000,VK=()=>{if(ZK)return;ZK=!0;try{s1.persist()}catch($){K(`alive marker write failed: ${$}`)}try{Q7(n0)}catch{}try{Q7(L1)}catch{}},c$,V7,u$,s1,DU,HK,FU,iJ,RU=30000,H4,H7,SU;var GK=O(()=>{GJ();t();t0();eW();U9();t6();t6();zG();GG();vG();pZ();S6();IG();wJ();mG();dG();k0();f();J2();V0();D7();w5();$K();{let $=k9(n0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(lJ(n0))try{Q7(n0)}catch{}}jU(PU(n0),{recursive:!0});YY(n0);process.on("exit",VK);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,V7=new IJ,u$=new s4,s1=new cJ({readMarker:HZ,writeMarker:VZ,sessions:()=>c$.values(),chatIdForSession:G6,sessionFor:zK,actor:u$,isShuttingDown:()=>i0,log:K}),DU=new v5(30000),HK=new Set,FU=jH({actor:u$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>NU($,Z)});iJ=eG({registry:c$,createSession:($,Z)=>{let J=new B$($,Z,{agentCards:V7.presentation,onLifecycleChange:MU,onCreateTempSession:UU,onDisbandTempSession:AU,onCancelAgentRuns:(Y,Q,V)=>V7.cancelSessionRuns(Y,Q,V)});return s1.transferPending(J),J},ensureChatForSession:zZ,disbandChatForSessionExact:GZ,chatIdForSession:G6,clearSessionConversationState:QZ,registerTempSessionLease:n5,hasTempSessionLease:a5,replaceTurnAnchors:e0,runExclusive:($,Z)=>u$.enqueue($,Z),log:K});H4=new Set,H7=WG({sendCard:c,updateCard:w2,sendText:E,dispatch:vZ,onWaitingChanged:($)=>c$.get($)?.refreshPendingAsks(),log:K});SU=LH({actor:u$,deduper:DU,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=w$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:CU,present:EU,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");K(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await xU($,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??""),`⚠️ ${X7(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:($)=>{dJ($)},onBackgroundError:($)=>{K(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${X7(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}})}});vU().catch(($)=>{K(`boot fatal: ${$}`),z4("boot fatal",1)})});V0();D7();import{existsSync as KK,unlinkSync as fU}from"node:fs";var _$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function hU(){if(!KK(E0)){if(process.stdin.isTTY){console.log(),console.log(`${_$.bold}${_$.yellow}Lodestar: 未找到配置, 启动安装向导...${_$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (kY(),bY));await Z();return}console.error(`${_$.red}Lodestar: 未找到配置 ${E0}${_$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${_$.green}lodestar-setup${_$.reset} 完成首次配置 (或直接运行 ${_$.green}lodestar-daemon${_$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=k9(n0);if($.state==="exit")console.error(`${_$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${_$.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(KK(n0))try{fU(n0)}catch{}await Promise.resolve().then(() => (GK(),wU))}hU().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});