@leviyuan/lodestar 0.18.19 → 0.18.21

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 dB}from"node:module";var fB=Object.create;var{getPrototypeOf:hB,defineProperty:d7,getOwnPropertyNames:IB}=Object;var gB=Object.prototype.hasOwnProperty;function mB($){return this[$]}var pB,cB,nY=($,Z,J)=>{var Y=$!=null&&typeof $==="object";if(Y){var Q=Z?pB??=new WeakMap:cB??=new WeakMap,V=Q.get($);if(V)return V}J=$!=null?fB(hB($)):{};let X=Z||!$||!$.__esModule?d7(J,"default",{value:$,enumerable:!0}):J;for(let H of IB($))if(!gB.call(X,H))d7(X,H,{get:mB.bind($,H),enumerable:!0});if(Y)Q.set($,X);return X};var aY=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var uB=($)=>$;function lB($,Z){this[$]=uB.bind(null,Z)}var S$=($,Z)=>{for(var J in Z)d7($,J,{get:Z[J],enumerable:!0,configurable:!0,set:lB.bind(Z,J)})};var O=($,Z)=>()=>($&&(Z=$($=0)),Z);var X2=dB(import.meta.url);var i7=aY((aO,tY)=>{var{homedir:oY}=X2("node:os"),{join:R4}=X2("node:path");function sY(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return R4(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return R4(process.env.LOCALAPPDATA??R4(oY(),"AppData","Local"),"Lodestar");return R4(oY(),".local","share","lodestar")}function iB(){return R4(sY(),"managed-claude-plugin")}tY.exports={lodestarDataDir:sY,managedClaudePluginDir:iB}});import{homedir as nB}from"node:os";import{join as s}from"node:path";function oB($,Z,J){if($)return $;if(Z)return s(Z,"lodestar");return J}function sB(){if(aB)return s(process.env.APPDATA??s(rY,"AppData","Roaming"),"Lodestar");return s(rY,".config","lodestar")}var Z3,rY,aB,n7,t,E0,a0,H2,a7,o7,s7,t7,r7,J3,P1,Y3,z2,G2,eY,$Q,ZQ,e7,JQ,YQ,$5,Z5,QQ,J5,q1,Q3;var Q0=O(()=>{Z3=nY(i7(),1),rY=nB(),aB=process.platform==="win32";n7=oB(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,sB()),t=Z3.lodestarDataDir(),E0=process.env.LODESTAR_CONFIG??s(n7,"config.toml"),a0=s(t,"daemon.pid"),H2=s(t,"daemon.log"),a7=s(t,"session-chat-map.json"),o7=s(t,"session-resume-map.json"),s7=s(t,"session-turns-map.json"),t7=s(t,"session-model-map.json"),r7=s(t,"temp-session-leases.json"),J3=s(t,"tasklist-map.json"),P1=s(t,"agent-runs"),Y3=s(t,"agent-session-ids.json"),z2=Z3.managedClaudePluginDir(),G2=s(t,"dsh"),eY=s(t,"codex-accounts"),$Q=s(t,"codex-accounts.json"),ZQ=s(t,"codex-quota-blocks.json"),e7=s(t,"agent-runtimes"),JQ=s(t,"context-window-cache.json"),YQ=s(t,"notify-callbacks.json"),$5=s(t,"alive-on-shutdown.json"),Z5=s(t,"inbox"),QQ=s(t,"file-deliveries"),J5=s(t,"file-delivery-groups.json"),q1=s(t,"debug.sock"),Q3=s(t,"debug-context.json")});import{execSync as VQ}from"node:child_process";import{readFileSync as XQ,writeFileSync as tB}from"node:fs";function rB(){return process.argv[1]??`pid:${process.pid}`}function eB($){try{if(process.platform==="linux")return XQ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return VQ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return VQ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function $_($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=eB($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function V3($){let Z="";try{Z=XQ($,"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($_(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function HQ($){tB($,`${process.pid}
4
- ${rB()}`)}var Y5=()=>{};import{execFile as Z_}from"node:child_process";import{readFile as J_}from"node:fs/promises";import{homedir as Y_}from"node:os";import{join as zQ}from"node:path";import{promisify as Q_}from"node:util";import{Address4 as X3,Address6 as H3}from"ip-address";function W2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function K3($){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 Q5($,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(X3.isValid(V))return X3.isValid(J)&&new X3(J).isInSubnet(new X3(V));if(H3.isValid(V))return H3.isValid(J)&&new H3(J).isInSubnet(new H3(V));throw Error("network proxy: invalid IP range in bypass list")}let X=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(X&&X[2]!==Y)return!1;let H=(X?X[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===H||J.endsWith(`.${H}`)})}function GQ($,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 WQ($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(K3($)||Q5($,W2(Z,"NO_PROXY")))return;let Y=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Q=W2(Z,Y)||W2(Z,"ALL_PROXY");if(Q)return GQ(Q,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(Q5($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?GQ(V,"system settings"):void 0}function W3($,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 X_($){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 H_($){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=W3(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=W3(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=W3(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 z3($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function z_($){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=z3(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=z3(Z.get(`.${Q}/host`));if(!V)continue;let X=new URL(W3(V,Z.get(`.${Q}/port`),Q==="socks"?"socks":"http"));if(Q==="http"&&Z.get(".http/use-authentication")==="true")X.username=z3(Z.get(".http/authentication-user")),X.password=z3(Z.get(".http/authentication-password"));Y[Q==="socks"?"all":Q]=X.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 G_($){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 X=V.indexOf("=");return[V.slice(0,X).trim(),V.slice(X+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 X=J.get(`${V}Proxy`);if(!X)continue;let H=X.replace(/\s+(\d+)$/,":$1");Q[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(H)?H:`${V==="socks"?"socks":"http"}://${H}`}return Q}async function G3($,Z,J=5000){let{stdout:Y}=await V_($,Z,{encoding:"utf8",timeout:J,maxBuffer:262144,windowsHide:!0});return Y}async function K_(){if(process.platform==="win32")return X_(JSON.parse(await G3("powershell.exe",["-NoProfile","-NonInteractive","-Command",W_],15000)));if(process.platform==="darwin")return H_(await G3("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=zQ(process.env.XDG_CONFIG_HOME||zQ(Y_(),".config"),"kioslaverc");try{let J=G_(await J_($,"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 G3("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return z_(await G3("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function B_($=K_,Z=process.env,J=Date.now){let Y;return async(Q)=>{if(K3(Q)||Q5(Q,W2(Z,"NO_PROXY"))||W2(Z,Q.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||W2(Z,"ALL_PROXY"))return WQ(Q,Z);if(!Y||Y.until<=J()){let V=$().catch((X)=>{if(Y?.value===V)Y=void 0;if(X instanceof Error&&X.message.startsWith("network proxy:"))throw X;let H=X instanceof Error?X.code??X.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${H})`,{cause:X})});Y={until:J()+30000,value:V}}return WQ(Q,Z,await Y.value)}}var V_,W_,KQ;var BQ=O(()=>{V_=Q_(Z_);W_=String.raw`
2
+ import{createRequire as K_}from"node:module";var J_=Object.create;var{getPrototypeOf:Q_,defineProperty:J7,getOwnPropertyNames:Y_}=Object;var V_=Object.prototype.hasOwnProperty;function X_($){return this[$]}var H_,z_,XY=($,Z,J)=>{var Q=$!=null&&typeof $==="object";if(Q){var Y=Z?H_??=new WeakMap:z_??=new WeakMap,V=Y.get($);if(V)return V}J=$!=null?J_(Q_($)):{};let X=Z||!$||!$.__esModule?J7(J,"default",{value:$,enumerable:!0}):J;for(let H of Y_($))if(!V_.call(X,H))J7(X,H,{get:X_.bind($,H),enumerable:!0});if(Q)Y.set($,X);return X};var HY=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var W_=($)=>$;function G_($,Z){this[$]=W_.bind(null,Z)}var v$=($,Z)=>{for(var J in Z)J7($,J,{get:Z[J],enumerable:!0,configurable:!0,set:G_.bind(Z,J)})};var O=($,Z)=>()=>($&&(Z=$($=0)),Z);var _2=K_(import.meta.url);var Q7=HY((MN,GY)=>{var{homedir:zY}=_2("node:os"),{join:b4}=_2("node:path");function WY(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return b4(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return b4(process.env.LOCALAPPDATA??b4(zY(),"AppData","Local"),"Lodestar");return b4(zY(),".local","share","lodestar")}function B_(){return b4(WY(),"managed-claude-plugin")}GY.exports={lodestarDataDir:WY,managedClaudePluginDir:B_}});import{homedir as __}from"node:os";import{join as s}from"node:path";function L_($,Z,J){if($)return $;if(Z)return s(Z,"lodestar");return J}function q_(){if(j_)return s(process.env.APPDATA??s(KY,"AppData","Roaming"),"Lodestar");return s(KY,".config","lodestar")}var G3,KY,j_,Y7,t,E0,$$,j2,V7,X7,H7,z7,W7,K3,T1,B3,L2,q2,BY,_Y,jY,G7,LY,qY,K7,B7,FY,_7,E1,_3;var V0=O(()=>{G3=XY(Q7(),1),KY=__(),j_=process.platform==="win32";Y7=L_(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,q_()),t=G3.lodestarDataDir(),E0=process.env.LODESTAR_CONFIG??s(Y7,"config.toml"),$$=s(t,"daemon.pid"),j2=s(t,"daemon.log"),V7=s(t,"session-chat-map.json"),X7=s(t,"session-resume-map.json"),H7=s(t,"session-turns-map.json"),z7=s(t,"session-model-map.json"),W7=s(t,"temp-session-leases.json"),K3=s(t,"tasklist-map.json"),T1=s(t,"agent-runs"),B3=s(t,"agent-session-ids.json"),L2=G3.managedClaudePluginDir(),q2=s(t,"dsh"),BY=s(t,"codex-accounts"),_Y=s(t,"codex-accounts.json"),jY=s(t,"codex-quota-blocks.json"),G7=s(t,"agent-runtimes"),LY=s(t,"context-window-cache.json"),qY=s(t,"notify-callbacks.json"),K7=s(t,"alive-on-shutdown.json"),B7=s(t,"inbox"),FY=s(t,"file-deliveries"),_7=s(t,"file-delivery-groups.json"),E1=s(t,"debug.sock"),_3=s(t,"debug-context.json")});import{execSync as PY}from"node:child_process";import{readFileSync as DY,writeFileSync as F_}from"node:fs";function P_(){return process.argv[1]??`pid:${process.pid}`}function D_($){try{if(process.platform==="linux")return DY(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return PY(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return PY(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function U_($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=D_($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function j3($){let Z="";try{Z=DY($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
+ `),Q=parseInt((J[0]??"").trim(),10),Y=(J[1]??"").trim();if(!Number.isFinite(Q)||Q<=0)return{state:"continue"};if(!Y)try{return process.kill(Q,0),{state:"exit",pid:Q}}catch{return{state:"continue"}}if(U_(Q,Y))return{state:"exit",pid:Q};return{state:"continue"}}function UY($){F_($,`${process.pid}
4
+ ${P_()}`)}var j7=()=>{};import{execFile as M_}from"node:child_process";import{readFile as A_}from"node:fs/promises";import{homedir as O_}from"node:os";import{join as MY}from"node:path";import{promisify as N_}from"node:util";import{Address4 as L3,Address6 as q3}from"ip-address";function F2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function U3($){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 L7($,Z=""){let J=$.hostname.replace(/^\[|\]$/g,"").toLowerCase(),Q=$.port||($.protocol==="https:"?"443":"80");return Z.split(/[,;\s]+/).filter(Boolean).some((Y)=>{let V=Y.toLowerCase();if(V==="*")return!0;if(V==="<local>")return!J.includes(".")&&!J.includes(":");if(V.includes("/")){if(L3.isValid(V))return L3.isValid(J)&&new L3(J).isInSubnet(new L3(V));if(q3.isValid(V))return q3.isValid(J)&&new q3(J).isInSubnet(new q3(V));throw Error("network proxy: invalid IP range in bypass list")}let X=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(X&&X[2]!==Q)return!1;let H=(X?X[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===H||J.endsWith(`.${H}`)})}function AY($,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 OY($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(U3($)||L7($,F2(Z,"NO_PROXY")))return;let Q=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Y=F2(Z,Q)||F2(Z,"ALL_PROXY");if(Y)return AY(Y,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(L7($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?AY(V,"system settings"):void 0}function D3($,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 Q=$.includes(":")&&!$.startsWith("[")?`[${$}]`:$;return`${J}://${Q}:${Z}`}function T_($){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((Q)=>Q.trim()).filter(Boolean)){let Q=J.match(/^(http|https|socks)=(.+)$/i),Y=Q?Q[2]:J,V=/^[a-z][\w+.-]*:\/\//i.test(Y)?Y:`http://${Y}`;if(!Q)Z.all=V;else if(Q[1].toLowerCase()==="socks")Z.all=`socks://${Y.replace(/^socks\w*:\/\//,"")}`;else Z[Q[1].toLowerCase()]=V}return Z}function E_($){let Z=(Y)=>$.match(new RegExp(`^\\s*${Y}\\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=D3(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=D3(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=D3(Z("SOCKSProxy"),Z("SOCKSPort"),"socks");let Q=$.match(/ExceptionsList\s*:\s*<array>\s*\{([^}]*)\}/)?.[1]??"";if(J.bypass=[...Q.matchAll(/^\s*\d+\s*:\s*(.*?)\s*$/gm)].map((Y)=>Y[1]).join(","),Z("ExcludeSimpleHostnames")==="1")J.bypass+=",<local>";return J}function F3($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function x_($){let Z=new Map($.split(`
5
+ `).filter(Boolean).map((Y)=>{let V=Y.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=F3(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 Q={};for(let Y of["http","https","socks"]){let V=F3(Z.get(`.${Y}/host`));if(!V)continue;let X=new URL(D3(V,Z.get(`.${Y}/port`),Y==="socks"?"socks":"http"));if(Y==="http"&&Z.get(".http/use-authentication")==="true")X.username=F3(Z.get(".http/authentication-user")),X.password=F3(Z.get(".http/authentication-password"));Q[Y==="socks"?"all":Y]=X.href}if(Z.get("/use-same-proxy")==="true"&&Q.http)Q.https=Q.http;return Q.bypass=[...(Z.get("/ignore-hosts")??"").matchAll(/'((?:\\.|[^'])*)'/g)].map((Y)=>Y[1]).join(","),Q}function S_($){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 X=V.indexOf("=");return[V.slice(0,X).trim(),V.slice(X+1).trim()]})),Q=J.get("ProxyType")??"0";if(Q==="0"||Q==="4")return{};if(Q!=="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 Y={bypass:J.get("NoProxyFor")};for(let V of["http","https","socks"]){let X=J.get(`${V}Proxy`);if(!X)continue;let H=X.replace(/\s+(\d+)$/,":$1");Y[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(H)?H:`${V==="socks"?"socks":"http"}://${H}`}return Y}async function P3($,Z,J=5000){let{stdout:Q}=await R_($,Z,{encoding:"utf8",timeout:J,maxBuffer:262144,windowsHide:!0});return Q}async function b_(){if(process.platform==="win32")return T_(JSON.parse(await P3("powershell.exe",["-NoProfile","-NonInteractive","-Command",C_],15000)));if(process.platform==="darwin")return E_(await P3("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=MY(process.env.XDG_CONFIG_HOME||MY(O_(),".config"),"kioslaverc");try{let J=S_(await A_($,"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 P3("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return x_(await P3("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function k_($=b_,Z=process.env,J=Date.now){let Q;return async(Y)=>{if(U3(Y)||L7(Y,F2(Z,"NO_PROXY"))||F2(Z,Y.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||F2(Z,"ALL_PROXY"))return OY(Y,Z);if(!Q||Q.until<=J()){let V=$().catch((X)=>{if(Q?.value===V)Q=void 0;if(X instanceof Error&&X.message.startsWith("network proxy:"))throw X;let H=X instanceof Error?X.code??X.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${H})`,{cause:X})});Q={until:J()+30000,value:V}}return OY(Y,Z,await Q.value)}}var R_,C_,NY;var RY=O(()=>{R_=N_(M_);C_=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
- `;KQ=B_()});import{Agent as __}from"node:http";import{Agent as j_}from"node:https";import{Readable as _Q}from"node:stream";import L_ from"node-fetch";import{HttpProxyAgent as P_}from"http-proxy-agent";import{HttpsProxyAgent as q_}from"https-proxy-agent";function M_($,Z){if(!Z)return $.protocol==="https:"?D_:F_;return $.protocol==="https:"?new q_(Z):new P_(Z)}async function U_($,Z,J){if(typeof Bun<"u"){let X=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[X.toLowerCase()]||process.env[X])){let H=await import("undici");return jQ??=new H.Agent,await H.fetch($,{...Z,redirect:"manual",dispatcher:jQ})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Y=new Request($,{...Z,redirect:"manual",duplex:"half"});if(Y.body&&!Y.headers.has("content-length")&&!Y.headers.has("transfer-encoding"))Y.headers.set("transfer-encoding","chunked");let Q=await L_($,{method:Y.method,headers:Object.fromEntries(Y.headers),body:Y.body?_Q.fromWeb(Y.body):void 0,signal:Y.signal,agent:M_($,J),redirect:"manual"}),V=Y.method==="HEAD"||[204,205,304].includes(Q.status)||!Q.body?null:_Q.toWeb(Q.body);return new Response(V,{status:Q.status,statusText:Q.statusText,headers:[...Q.headers]})}async function LQ($,Z,J,Y=KQ){let Q=new URL($),V={...Z};for(let X=0;;X++){if(!["http:","https:"].includes(Q.protocol))throw Error(`network: unsupported URL protocol ${Q.protocol}`);if(J&&!K3(Q))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let H=J?void 0:await Y(Q),z=await U_(Q,V,H),G=z.headers.get("location");if(![301,302,303,307,308].includes(z.status)||!G||Z.redirect==="manual")return z;if(await z.body?.cancel(),Z.redirect==="error")throw Error("network: redirect rejected");if(X>=20)throw Error("network: too many redirects");let W=new URL(G,Q),K=new Headers(V.headers);if(W.origin!==Q.origin)for(let L of["authorization","proxy-authorization","cookie","host"])K.delete(L);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 L of["content-type","content-length","content-encoding"])K.delete(L)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=K,Q=W}}function z0($,Z={}){return LQ($,Z,!1)}function PQ($,Z={}){return LQ($,Z,!0)}var F_,D_,jQ;var o0=O(()=>{BQ();F_=new __({keepAlive:!0}),D_=new j_({keepAlive:!0})});function K2($,Z=[]){let J=$ instanceof Error?$.message:String($);if($ instanceof Error&&$.cause instanceof Error&&!J.includes($.cause.message))J+=`;${$.cause.message}`;for(let Q of Z)if(Q)J=J.replaceAll(Q,"[redacted]");let Y="";if(/HTTP 401\b|code=(?:401|1000|1001|1003|1005)\b|authentication_error/i.test(J))Y="认证失败,请检查 API Key 是否完整、有效,并确认 Key 与接口所属平台一致";else if(/HTTP 403\b|code=(?:403|1220)\b|permission_error/i.test(J))Y="访问被拒绝,请检查账号及 API Key 的接口权限";else if(/HTTP 429\b|code=(?:429|1302|1305|1308|1309|1310|1311)\b/i.test(J))Y="请求受限,请按接口说明检查套餐、额度或稍后重试";else if(/timeout|timed out|aborted|超时/i.test(J))Y="请求超时,请检查网络和代理后重试";else if(/fetch failed|failed to fetch|ECONN|ENOTFOUND|EAI_AGAIN|network|代理/i.test(J))Y="连接失败,请检查网络、代理和接口地址后重试";else if(/HTTP 404\b/i.test(J))Y="模型接口不存在,请检查 API 地址";else if(/HTTP 5\d\d\b/i.test(J))Y="上游服务异常,请稍后重试";else if(/data 数组|有效 JSON|无效条目|模型 id 无效/i.test(J))Y="模型接口返回异常,请检查 API 地址;持续出现时请反馈诊断信息";else if(/模型目录为空|catalog is empty/i.test(J))Y="账号未返回可用模型,请检查套餐和模型权限";return Y&&!J.startsWith(Y)?`${Y}(${J})`:J}function V5($){return $!==null&&typeof $==="object"&&!Array.isArray($)}function qQ($){return typeof $==="string"||typeof $==="number"?String($):void 0}async function l$($,Z,J){try{if(!Z.trim())throw Error(`${J}: 请填写 API Key`);return await A_($,Z,J)}catch(Y){throw Error(K2(Y,[Z]))}}async function A_($,Z,J){let Y=await z0($,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)}),Q=await Y.text(),V;try{V=JSON.parse(Q)}catch(K){throw Error(`${J} HTTP ${Y.status}: 响应不是有效 JSON`,{cause:K})}let X=V5(V)?V:void 0,H=V5(X?.error)?X.error:void 0,z=qQ(H?.code??H?.type??X?.code),G=qQ(H?.message??X?.msg??X?.message??X?.error),W=X?.success===!1||X?.error!=null||z!==void 0&&z!=="0"&&z!=="200";if(!Y.ok||W){let K=[z!==void 0?`code=${z}`:"",G].filter(Boolean).join(": "),_=`${J} HTTP ${Y.status}${K?`: ${K}`:""}`;throw Error(Z?_.replaceAll(Z,"[redacted]"):_)}if(!Array.isArray(X?.data))throw Error(`${J} 缺少 data 数组`);if(!X.data.length)throw Error(`${J} 模型目录为空`);if(!X.data.every(V5))throw Error(`${J} 模型目录包含无效条目`);return X.data}var T4=O(()=>{o0()});function E4($){let Z;try{Z=new URL($)}catch{throw Error("GLM 接口地址无效,请使用 https://open.bigmodel.cn/api/anthropic 或 https://api.z.ai/api/anthropic")}if(Z.protocol!=="https:"||!["open.bigmodel.cn","dev.bigmodel.cn","api.z.ai"].includes(Z.hostname)||Z.username||Z.password||Z.search||Z.hash||Z.pathname.replace(/\/+$/,"")!=="/api/anthropic")throw Error("GLM Claude Code 需要智谱或 Z.ai 的 /api/anthropic HTTPS 端点;Key 须与平台一致");return Z.toString().replace(/\/+$/,"")}async function _2($,Z){return(await l$(`${E4($)}/v1/models`,Z,"GLM models")).map((Y)=>{let Q=typeof Y.display_name==="string"&&Y.display_name?Y.display_name:Y.id;if(typeof Q!=="string"||!Q.trim())throw Error("GLM models 模型 id 无效");return Q})}var B2="https://open.bigmodel.cn/api/anthropic";var x4=O(()=>{T4()});import{chmodSync as O_,closeSync as X5,fsyncSync as FQ,mkdirSync as N_,openSync as DQ,renameSync as R_,unlinkSync as T_,writeFileSync as E_}from"node:fs";import{randomUUID as x_}from"node:crypto";import{dirname as MQ}from"node:path";function k_($){let Z=MQ($);N_(Z,{recursive:!0,mode:b_})}function UQ($,Z,J){k_($);let Y=`${$}.${process.pid}.${x_()}.tmp`,Q=null;try{Q=DQ(Y,"wx",J),E_(Q,Z),FQ(Q),X5(Q),Q=null,R_(Y,$);try{O_($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=DQ(MQ($),"r"),FQ(V)}catch{}finally{if(V!==null)try{X5(V)}catch{}}}}catch(V){if(Q!==null)try{X5(Q)}catch{}try{T_(Y)}catch{}throw V}}function g0($,Z){UQ($,Z,S_)}function AQ($,Z){UQ($,Z,C_)}function o($,Z){g0($,JSON.stringify(Z,null,2)+`
45
- `)}var S_=384,C_=448,b_=448;var x0=()=>{};import{execFile as y_}from"node:child_process";import{spawn as w_}from"cross-spawn";function f_($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{y_("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 H5($,Z,J={}){Z?.throwIfAborted();let Y=J.platform??process.platform,Q=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,H)=>{let z=(J.spawn??w_)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${v_}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),G="",W,K,_=!1,L=!1,j,q=(x)=>{G=(G+x.toString()).slice(-16384)};z.stdout.on("data",q),z.stderr.on("data",q);let F=(x)=>{if(_)return;if(_=!0,clearTimeout(A),j)clearTimeout(j);if(Z?.removeEventListener("abort",U),x)H(x);else X()},R=(x)=>new B3(`${W?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${x}; partial directory retained: ${$}
47
- ${G}`),D=(x)=>{if(_||L||K)return;W??=Error(x),j=setTimeout(()=>F(R(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(L)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Y==="win32")await(J.terminateWindows??f_)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((S)=>F(R(S instanceof Error?S.message:String(S))))},U=()=>D("Agent runtime install aborted"),A=setTimeout(()=>D(`Agent runtime install timed out after ${Q}ms`),Q);if(Z?.addEventListener("abort",U,{once:!0}),z.on("error",(x)=>{if(W??=x,!z.pid)F(Error(`${x.message}
48
- ${G}`))}),z.once("close",async(x,S)=>{L=!0,clearTimeout(A),Z?.removeEventListener("abort",U);try{await K}catch(h){F(R(h instanceof Error?h.message:String(h)));return}if(W||x!==0)F(Error(`${W?.message??`npm install exited code=${x} signal=${S}`}
49
- ${G}`));else F()}),Z?.aborted)U()})}var v_="https://registry.npmjs.org",B3;var z5=O(()=>{B3=class B3 extends Error{}});import{createHash as h_,randomUUID as I_}from"node:crypto";import{createRequire as g_}from"node:module";import{existsSync as _3,readFileSync as OQ}from"node:fs";import{mkdir as NQ,mkdtemp as m_,readFile as RQ,rename as TQ,rm as S4,writeFile as EQ}from"node:fs/promises";import{join as m0,isAbsolute as p_}from"node:path";import{fileURLToPath as c_,pathToFileURL as u_}from"node:url";function xQ($,Z=e7){let J=m0(Z,$,"current.json");if(!_3(J))return null;let Y=JSON.parse(OQ(J,"utf8"));if(!Number.isFinite(Y.checkedAt)||Y.directory!==void 0&&!p_(Y.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Y}function j3($){let Z=xQ($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!_3(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function G5($,Z){return g_(m0(j3($),"package.json")).resolve(Z)}function b4($,Z){let J=m0(j3($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!_3(J))throw Error(`${$} executable missing: ${J}`);return J}async function SQ(){return import(u_(G5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function n_($,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 X=await z0(`${i_}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Y.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let H=await X.json();if(H.name!==$||typeof H.version!=="string"||!H.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return H}finally{clearTimeout(V),J?.removeEventListener("abort",Q)}}async function a_($,Z){let J={};if($!=="dsh"){let X=await Promise.all(C4[$].map((H)=>Z(H,"latest")));for(let H of X)J[H.name]=H.version;return J}let Y=await Z("@deepseek-ai/dsh","latest"),Q=new Set(C4.dsh),V=new Set;while(Q.size){let X=[...Q].slice(0,12);for(let z of X)Q.delete(z),V.add(z);let H=await Promise.all(X.map((z)=>z===Y.name?Y:Z(z,Y.version)));for(let z of H){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 G of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(G.startsWith("@deepseek-ai/dsh")&&!V.has(G))Q.add(G)}}return J}async function d$($,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 o_($,Z){let J=m0($,`current-${I_()}.json`),Y;try{await EQ(J,JSON.stringify(Z)+`
50
- `,{mode:384}),await d$(()=>TQ(J,m0($,"current.json")))}catch(Q){throw Y=Q,Q}finally{try{await d$(()=>S4(J,{force:!0}))}catch(Q){if(Y)throw AggregateError([Y,Q],`${j2(Y)}; state temporary file cleanup failed: ${j2(Q)}`);throw Q}}}async function s_($,Z){let J=m0($,"update.lock"),Y=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await NQ(J);try{await d$(async()=>g0(m0(J,"pid"),String(process.pid)))}catch(Q){try{await d$(()=>S4(J,{recursive:!0}))}catch(V){throw AggregateError([Q,V],`${j2(Q)}; runtime update lock cleanup failed: ${j2(V)}`)}throw Q}return()=>d$(()=>S4(J,{recursive:!0}))}catch(Q){if(Q.code!=="EEXIST")throw Q;try{let V=Number(await RQ(m0(J,"pid"),"utf8"));if(!Number.isSafeInteger(V)||V<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(V,0)}catch(X){if(X.code!=="ESRCH")throw X;await d$(()=>S4(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 L3($,Z={}){let J=Z.root??e7,Y=m0(J,$);await NQ(Y,{recursive:!0,mode:448});let Q=await s_(Y,Z.signal),V,X,H=!1;try{let z=xQ($,J);Z.report?.(`${$}: 检查 upstream latest`);let G=await a_($,Z.metadata??((q,F)=>n_(q,F,Z.signal)));Z.signal?.throwIfAborted();let W=JSON.parse(OQ(c_(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=h_("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(G).sort(),security:W,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=m0(Y,K);if(!_3(_)){V=await m_(m0(Y,".install-")),await EQ(m0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:G[C4[$][0]],private:!0,type:"module",dependencies:G,overrides:{...W,...$==="dsh"?G:{}}})+`
51
- `,{mode:384}),await(Z.install??H5)(V,Z.signal);for(let[F,R]of Object.entries(G)){let D=JSON.parse(await RQ(m0(V,"node_modules",F,"package.json"),"utf8"));if(D.version!==R)throw Error(`npm installed ${F}@${D.version}, expected ${R}`)}Z.signal?.throwIfAborted();let q=V;await d$(()=>TQ(q,_)),V=void 0}let L={directory:_,versions:G,checkedAt:Date.now()},j=z?.directory===_;return await o_(Y,L),Z.report?.(`${$}: ${C4[$][0]}@${G[C4[$][0]]}${j?" 已是 latest":" 已更新,新进程使用新版"}`),L}catch(z){throw X=z,H=z instanceof B3,z}finally{let z=[];if(V&&!H){let G=V;try{await d$(()=>S4(G,{recursive:!0}))}catch(W){z.push(W)}}try{await Q()}catch(G){z.push(G)}if(z.length){let G=X?[X,...z]:z;throw AggregateError(G,G.map(j2).join("; "))}}}function CQ($,Z={}){let J=l_.filter((Y)=>Z.enabled?.[Y]===!0).map((Y)=>{let Q=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??L3)(Y,{report:$,signal:Q.signal}).catch((H)=>$(`${Y} 自动更新未完成: ${j2(H)}`)).finally(()=>{V=void 0})},d_);return X.unref(),()=>{clearInterval(X),Q.abort()}});return()=>{for(let Y of J)Y()}}var l_,d_=21600000,i_="https://registry.npmjs.org",C4,j2=($)=>$ instanceof Error?$.message:String($);var L2=O(()=>{o0();Q0();z5();x0();z5();l_=["codex","claude","dsh"],C4={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 kQ;var bQ=O(()=>{kQ={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 fQ={};S$(fQ,{writeClaudeGlmEnv:()=>vQ,runSetup:()=>Bj});import{execFileSync as r_,spawn as q3}from"node:child_process";import{spawn as e_}from"cross-spawn";import{existsSync as K5,mkdirSync as wQ,readFileSync as $j}from"node:fs";import{createInterface as Zj}from"node:readline/promises";import{dirname as Jj,join as B5}from"node:path";import{homedir as Yj}from"node:os";import{fileURLToPath as Qj}from"node:url";async function F1($,Z={}){while(!0){let J=Z.default?`${P.dim} [${Z.default}]${P.reset}`:"",Y=(await k4.question(`${P.cyan}? ${P.reset}${$}${J}
52
- ${P.green}>${P.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${P.red}必填,请重新输入${P.reset}`);continue}return Y}}function Vj($){let Z="═".repeat(58);console.log(`
53
- ${P.bold}${P.cyan}╔${Z}╗${P.reset}`),console.log(`${P.bold}${P.cyan}║ ${$.padEnd(54)} ║${P.reset}`),console.log(`${P.bold}${P.cyan}╚${Z}╝${P.reset}
54
- `)}function P3($,Z,J){console.log(`
55
- ${P.bold}${P.yellow}[${$}/${Z}] ${J}${P.reset}
56
- `)}function W5($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function yQ($){try{let Z=r_($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function Xj($){return new Promise((Z)=>{let J=e_($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function Hj(){return process.env.CLAUDE_CONFIG_DIR||B5(Yj(),".claude")}async function zj($){let Z=await _2(B2,$),J=(z)=>{let G=z.match(/(\d+(?:\.\d+)?)/);return G?Number(G[1]):-1},Q=[...Z.filter((z)=>!/-Turbo|-Air/i.test(z))].sort((z,G)=>J(G)-J(z)),V=Q[0],X=Q[Q.length-1];if(!V)throw Error("GLM 模型目录中没有可用于 Claude Code slots 的模型");let H={ANTHROPIC_DEFAULT_OPUS_MODEL:`${V}[1m]`,ANTHROPIC_DEFAULT_SONNET_MODEL:`${V}[1m]`};if(X&&X!==V)H.ANTHROPIC_DEFAULT_HAIKU_MODEL=X;return H}async function vQ($){try{let Z=Hj();wQ(Z,{recursive:!0});let J=B5(Z,"settings.json"),Y={};if(K5(J)){let H=$j(J,"utf8");try{let z=JSON.parse(H);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=await zj($),X={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:B2,API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"};return Object.assign(X,V),Y.env={...Q,...X},g0(J,JSON.stringify(Y,null,2)+`
57
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function Gj($){try{if(process.platform==="win32")q3(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")q3("open",[$],{detached:!0,stdio:"ignore"}).unref();else q3("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Wj($,Z){try{let Y=await(await z0("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 Kj(){try{let $=Jj(Qj(import.meta.url)),Z=B5($,"lodestar.js");if(!K5(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=q3(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function Bj(){if(!process.stdin.isTTY)console.error(`${P.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${P.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(K5(E0)){if(console.log(`${P.yellow}发现已有配置: ${E0}${P.reset}`),(await F1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),k4.close();return}}Vj("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(` ${P.dim}1) 确保 Claude Code CLI 已装好${P.reset}`),console.log(` ${P.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${P.reset}`),console.log(` ${P.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${P.reset}`),console.log(` ${P.dim}4) 工作目录, 自动启动 daemon${P.reset}`),console.log(),await k4.question(`${P.dim}按 Enter 开始 (Ctrl+C 退出)...${P.reset}`),P3(1,4,"准备 Claude Code CLI"),await L3("claude",{report:(W)=>console.log(W)}),console.log(`${P.green}✓ Claude Code / SDK 已更新${P.reset}: ${P.dim}${b4("claude","claude")}${P.reset}`),console.log(),console.log(`${P.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${P.reset}`),console.log(`${P.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${P.reset}`),P3(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${P.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${P.reset}`),console.log(` ${P.dim}此项可选,直接回车跳过;以后可在群内发送 glm-setup <api_key> 补配。${P.reset}`),console.log(` ${P.dim}使用本机 Claude Code 或 Codex 订阅不需要 GLM Key。此处填写智谱国内站 Key;Z.ai 请之后用 glm-setup 指定对应地址。${P.reset}`),console.log();while(!0){let W=await F1("GLM API key (直接回车跳过)",{});if(!W){console.log(`${P.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${P.reset}`);break}let K=await vQ(W);if("path"in K){console.log(`${P.green}✓ GLM 路由已写入${P.reset}: ${P.dim}${K.path}${P.reset}`),console.log(`${P.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${P.reset}`);break}else console.log(`${P.red}✗ GLM 配置失败:${P.reset} ${K.error}`),console.log(`${P.dim}请按错误提示处理后重新输入;直接回车可跳过,之后用群命令补配。${P.reset}`)}if(console.log(),console.log(`${P.bold}Codex (可选第二后端)${P.reset}`),console.log(` ${P.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${P.reset}`),(await F1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await L3("codex",{report:(K)=>console.log(K)});let W=b4("codex","codex");if(yQ(W))console.log(`${P.green}✓ Codex 已登录 ChatGPT${P.reset}`);else if(console.log(`${P.dim}启动 \`codex login\`...${P.reset}`),await Xj(W)&&yQ(W))console.log(`${P.green}✓ Codex 已登录 ChatGPT${P.reset}`);else console.log(`${P.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${P.reset}`)}else console.log(`${P.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${P.reset}`);P3(3,4,"Feishu 自建应用");let Z="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${P.cyan}${Z}${P.reset}`),Gj(Z),console.log(`${P.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${P.reset}`),console.log(),console.log(`${P.bold}详细操作步骤:${P.reset}`),console.log(),console.log(` ${P.bold}① 创建应用${P.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${P.dim}Lodestar${P.reset}), logo 随意。`),console.log(),console.log(` ${P.bold}② 添加机器人能力${P.reset}`),console.log(` 左侧菜单 "${P.cyan}添加应用能力${P.reset}" → 找到 "机器人" → 点 "${P.bold}添加${P.reset}" 按钮。`),console.log(),console.log(` ${P.bold}③ 申请权限 (左侧 "${P.cyan}权限管理${P.reset}" → "${P.bold}批量导入/导出权限${P.reset}")${P.reset}`),console.log(` ${P.yellow}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${P.reset}`),console.log(JSON.stringify(kQ,null,2)),console.log(` ${P.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${P.reset}`),console.log(` ${P.dim}清单包含以下用途;也可按名称逐项开通:${P.reset}`),console.log(` ${P.dim}账号与认证信息 (排障):${P.reset}`),console.log(` • ${P.bold}verification:verification_information:readonly${P.reset} ${P.dim}# 查看账号主体认证状态${P.reset}`),console.log(` • ${P.bold}tenant:tenant:readonly${P.reset} ${P.dim}# 查看租户基本信息${P.reset}`),console.log(` ${P.dim}消息类:${P.reset}`),console.log(` • ${P.bold}im:message:send_as_bot${P.reset} ${P.dim}# 以机器人身份发消息${P.reset}`),console.log(` • ${P.bold}im:message${P.reset} ${P.dim}# 接收/操作消息 (核心)${P.reset}`),console.log(` • ${P.bold}im:chat${P.reset} ${P.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${P.reset}`),console.log(` • ${P.bold}im:chat:create${P.reset} ${P.dim}# wt: 自动创建 worktree 群${P.reset}`),console.log(` • ${P.bold}im:chat:delete${P.reset} ${P.dim}# wt: 解散 worktree 群${P.reset}`),console.log(` • ${P.bold}im:chat.members:read${P.reset} ${P.dim}# wt: 判断发起人是否已在群内${P.reset}`),console.log(` • ${P.bold}im:chat.members:write_only${P.reset} ${P.dim}# wt: 把发起人拉进已有 worktree 群${P.reset}`),console.log(` • ${P.bold}im:resource${P.reset} ${P.dim}# 上传/下载附件 (图文双向)${P.reset}`),console.log(` • ${P.bold}im:message.urgent${P.reset} ${P.dim}# 加急推送 (锁屏通知 / Ask)${P.reset}`),console.log(` • ${P.bold}im:message.group_msg${P.reset} ${P.dim}# 敏感: 接收群里所有消息${P.reset}`),console.log(` ${P.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${P.reset}`),console.log(` ${P.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${P.reset}`),console.log(` • ${P.bold}im:message.group_at_msg:readonly${P.reset} ${P.dim}# 读 @ 机器人消息 (兜底)${P.reset}`),console.log(` ${P.dim}卡片类 (Card Kit):${P.reset}`),console.log(` • ${P.bold}cardkit:card:read${P.reset} ${P.dim}# 读卡片状态${P.reset}`),console.log(` • ${P.bold}cardkit:card:write${P.reset} ${P.dim}# 创建/更新卡片 (流式渲染核心)${P.reset}`),console.log(` ${P.dim}云空间交付 (权限预先开通,功能仍按群开启):${P.reset}`),console.log(` • ${P.bold}drive:drive${P.reset} ${P.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${P.reset}`),console.log(` • ${P.bold}drive:file:upload${P.reset} ${P.dim}# 文件夹改名接口单独要求此权限${P.reset}`),console.log(` ${P.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${P.reset}`),console.log(` ${P.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${P.reset}`),console.log(),console.log(` ${P.bold}④ 订阅事件 (左侧 "${P.cyan}事件与回调${P.reset}", 拆两个子页:)${P.reset}`),console.log(` ${P.dim}a)${P.reset} ${P.bold}事件配置${P.reset} 页:`),console.log(` ${P.yellow}• "订阅方式" → 选 "长连接" → 点保存${P.reset}`),console.log(` • 添加事件: ${P.bold}im.message.receive_v1${P.reset} ${P.dim}# 收群消息${P.reset}`),console.log(` ${P.dim}b)${P.reset} ${P.bold}回调配置${P.reset} 页:`),console.log(` ${P.yellow}• "订阅方式" → 选 "长连接" → 点保存${P.reset}`),console.log(` • 添加事件: ${P.bold}card.action.trigger${P.reset} ${P.dim}# 卡片按钮点击回调${P.reset}`),console.log(),console.log(` ${P.bold}⑤ 发布版本${P.reset}`),console.log(` 页面顶部 "${P.bold}创建版本${P.reset}" → 滚到底点 "${P.bold}保存${P.reset}" → 弹框点 "${P.bold}发布${P.reset}"。`),console.log(` ${P.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${P.reset}`),console.log(),console.log(` ${P.bold}⑥ 拿凭据${P.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${P.bold}App ID${P.reset} (${P.dim}cli_...${P.reset}) 和 ${P.bold}App Secret${P.reset}, 待会粘到下面。`),console.log(),console.log(` ${P.bold}⑦ 把机器人拉进群${P.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${P.yellow}群名要等于 projects_root 下的项目目录名${P.reset} (下一步设, 默认是用户主目录)。`),console.log();let J="",Y="";while(!0){J=await F1("App ID (以 cli_ 开头)",{required:!0}),Y=await F1("App Secret",{required:!0}),console.log(`${P.dim}测试中... (调 tenant_access_token endpoint)${P.reset}`);let W=await Wj(J,Y);if(W.ok){console.log(`${P.green}✓ Feishu 凭据测试通过${P.reset}`);break}if(console.log(`${P.red}✗ 测试失败:${P.reset} ${W.error}`),console.log(`${P.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${P.reset}`),console.log(),(await F1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${P.yellow}已取消, 配置未写盘。${P.reset}`),k4.close(),process.exit(1)}P3(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let Q=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",V=await F1("projects_root",{default:Q});wQ(n7,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${W5(J)}"`,`app_secret = "${W5(Y)}"`,"","[runtime]",`projects_root = "${W5(V)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];g0(E0,X.join(`
44
+ `;NY=k_()});import{Agent as w_}from"node:http";import{Agent as y_}from"node:https";import{Readable as TY}from"node:stream";import v_ from"node-fetch";import{HttpProxyAgent as f_}from"http-proxy-agent";import{HttpsProxyAgent as h_}from"https-proxy-agent";function m_($,Z){if(!Z)return $.protocol==="https:"?g_:I_;return $.protocol==="https:"?new h_(Z):new f_(Z)}async function p_($,Z,J){if(typeof Bun<"u"){let X=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[X.toLowerCase()]||process.env[X])){let H=await import("undici");return EY??=new H.Agent,await H.fetch($,{...Z,redirect:"manual",dispatcher:EY})}return globalThis.fetch($.href,{...Z,redirect:"manual",...J?{proxy:J}:{}})}let Q=new Request($,{...Z,redirect:"manual",duplex:"half"});if(Q.body&&!Q.headers.has("content-length")&&!Q.headers.has("transfer-encoding"))Q.headers.set("transfer-encoding","chunked");let Y=await v_($,{method:Q.method,headers:Object.fromEntries(Q.headers),body:Q.body?TY.fromWeb(Q.body):void 0,signal:Q.signal,agent:m_($,J),redirect:"manual"}),V=Q.method==="HEAD"||[204,205,304].includes(Y.status)||!Y.body?null:TY.toWeb(Y.body);return new Response(V,{status:Y.status,statusText:Y.statusText,headers:[...Y.headers]})}async function xY($,Z,J,Q=NY){let Y=new URL($),V={...Z};for(let X=0;;X++){if(!["http:","https:"].includes(Y.protocol))throw Error(`network: unsupported URL protocol ${Y.protocol}`);if(J&&!U3(Y))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let H=J?void 0:await Q(Y),z=await p_(Y,V,H),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(X>=20)throw Error("network: too many redirects");let G=new URL(W,Y),K=new Headers(V.headers);if(G.origin!==Y.origin)for(let L of["authorization","proxy-authorization","cookie","host"])K.delete(L);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 L of["content-type","content-length","content-encoding"])K.delete(L)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=K,Y=G}}function X0($,Z={}){return xY($,Z,!1)}function SY($,Z={}){return xY($,Z,!0)}var I_,g_,EY;var u0=O(()=>{RY();I_=new w_({keepAlive:!0}),g_=new y_({keepAlive:!0})});function w0($,Z=[]){let J=$ instanceof Error?$.message:String($);if($ instanceof Error&&$.cause instanceof Error&&!J.includes($.cause.message))J+=`;${$.cause.message}`;for(let Y of Z)if(Y)J=J.replaceAll(Y,"[redacted]");let Q="";if(/HTTP 401\b|code=(?:401|1000|1001|1003|1005)\b|authentication_error/i.test(J))Q="认证失败,请检查 API Key 是否完整、有效,并确认 Key 与接口所属平台一致";else if(/HTTP 403\b|code=(?:403|1220)\b|permission_error/i.test(J))Q="访问被拒绝,请检查账号及 API Key 的接口权限";else if(/HTTP 429\b|code=(?:429|1302|1305|1308|1309|1310|1311)\b/i.test(J))Q="请求受限,请按接口说明检查套餐、额度或稍后重试";else if(/timeout|timed out|aborted|超时/i.test(J))Q="请求超时,请检查网络和代理后重试";else if(/fetch failed|failed to fetch|ECONN|ENOTFOUND|EAI_AGAIN|network|代理/i.test(J))Q="连接失败,请检查网络、代理和接口地址后重试";else if(/HTTP 404\b/i.test(J))Q="模型接口不存在,请检查 API 地址";else if(/HTTP 5\d\d\b/i.test(J))Q="上游服务异常,请稍后重试";else if(/data 数组|有效 JSON|无效条目|模型 id 无效/i.test(J))Q="模型接口返回异常,请检查 API 地址;持续出现时请反馈诊断信息";else if(/模型目录为空|catalog is empty/i.test(J))Q="账号未返回可用模型,请检查套餐和模型权限";return Q&&!J.startsWith(Q)?`${Q}(${J})`:J}function q7($){return $!==null&&typeof $==="object"&&!Array.isArray($)}function CY($){return typeof $==="string"||typeof $==="number"?String($):void 0}async function A$($,Z,J){try{if(!Z.trim())throw Error(`${J}: 请填写 API Key`);return await c_($,Z,J)}catch(Q){throw Error(w0(Q,[Z]))}}async function c_($,Z,J){let Q=await X0($,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)}),Y=await Q.text(),V;try{V=JSON.parse(Y)}catch(K){throw Error(`${J} HTTP ${Q.status}: 响应不是有效 JSON`,{cause:K})}let X=q7(V)?V:void 0,H=q7(X?.error)?X.error:void 0,z=CY(H?.code??H?.type??X?.code),W=CY(H?.message??X?.msg??X?.message??X?.error),G=X?.success===!1||X?.error!=null||z!==void 0&&z!=="0"&&z!=="200";if(!Q.ok||G){let K=[z!==void 0?`code=${z}`:"",W].filter(Boolean).join(": "),_=`${J} HTTP ${Q.status}${K?`: ${K}`:""}`;throw Error(Z?_.replaceAll(Z,"[redacted]"):_)}if(!Array.isArray(X?.data))throw Error(`${J} 缺少 data 数组`);if(!X.data.length)throw Error(`${J} 模型目录为空`);if(!X.data.every(q7))throw Error(`${J} 模型目录包含无效条目`);return X.data}var P2=O(()=>{u0()});function k4($){let Z;try{Z=new URL($)}catch{throw Error("GLM 接口地址无效,请使用 https://open.bigmodel.cn/api/anthropic 或 https://api.z.ai/api/anthropic")}if(Z.protocol!=="https:"||!["open.bigmodel.cn","dev.bigmodel.cn","api.z.ai"].includes(Z.hostname)||Z.username||Z.password||Z.search||Z.hash||Z.pathname.replace(/\/+$/,"")!=="/api/anthropic")throw Error("GLM Claude Code 需要智谱或 Z.ai 的 /api/anthropic HTTPS 端点;Key 须与平台一致");return Z.toString().replace(/\/+$/,"")}async function U2($,Z){return(await A$(`${k4($)}/v1/models`,Z,"GLM models")).map((Q)=>{let Y=typeof Q.display_name==="string"&&Q.display_name?Q.display_name:Q.id;if(typeof Y!=="string"||!Y.trim())throw Error("GLM models 模型 id 无效");return Y})}var D2="https://open.bigmodel.cn/api/anthropic";var w4=O(()=>{P2()});import{chmodSync as u_,closeSync as F7,fsyncSync as bY,mkdirSync as l_,openSync as kY,renameSync as d_,unlinkSync as i_,writeFileSync as n_}from"node:fs";import{randomUUID as a_}from"node:crypto";import{dirname as wY}from"node:path";function r_($){let Z=wY($);l_(Z,{recursive:!0,mode:t_})}function yY($,Z,J){r_($);let Q=`${$}.${process.pid}.${a_()}.tmp`,Y=null;try{Y=kY(Q,"wx",J),n_(Y,Z),bY(Y),F7(Y),Y=null,d_(Q,$);try{u_($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=kY(wY($),"r"),bY(V)}catch{}finally{if(V!==null)try{F7(V)}catch{}}}}catch(V){if(Y!==null)try{F7(Y)}catch{}try{i_(Q)}catch{}throw V}}function l0($,Z){yY($,Z,o_)}function vY($,Z){yY($,Z,s_)}function o($,Z){l0($,JSON.stringify(Z,null,2)+`
45
+ `)}var o_=384,s_=448,t_=448;var x0=()=>{};import{execFile as e_}from"node:child_process";import{spawn as $j}from"cross-spawn";function Jj($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{e_("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Q,Y,V)=>{if(Q)J(Error(`taskkill npm installer PID ${$} failed: ${Q.message}
46
+ ${Y}${V}`));else Z()})})}async function P7($,Z,J={}){Z?.throwIfAborted();let Q=J.platform??process.platform,Y=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,H)=>{let z=(J.spawn??$j)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${Zj}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),W="",G,K,_=!1,L=!1,j,q=(T)=>{W=(W+T.toString()).slice(-16384)};z.stdout.on("data",q),z.stderr.on("data",q);let P=(T)=>{if(_)return;if(_=!0,clearTimeout(M),j)clearTimeout(j);if(Z?.removeEventListener("abort",U),T)H(T);else X()},N=(T)=>new M3(`${G?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${T}; partial directory retained: ${$}
47
+ ${W}`),D=(T)=>{if(_||L||K)return;G??=Error(T),j=setTimeout(()=>P(N(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(L)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??Jj)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((x)=>P(N(x instanceof Error?x.message:String(x))))},U=()=>D("Agent runtime install aborted"),M=setTimeout(()=>D(`Agent runtime install timed out after ${Y}ms`),Y);if(Z?.addEventListener("abort",U,{once:!0}),z.on("error",(T)=>{if(G??=T,!z.pid)P(Error(`${T.message}
48
+ ${W}`))}),z.once("close",async(T,x)=>{L=!0,clearTimeout(M),Z?.removeEventListener("abort",U);try{await K}catch(w){P(N(w instanceof Error?w.message:String(w)));return}if(G||T!==0)P(Error(`${G?.message??`npm install exited code=${T} signal=${x}`}
49
+ ${W}`));else P()}),Z?.aborted)U()})}var Zj="https://registry.npmjs.org",M3;var D7=O(()=>{M3=class M3 extends Error{}});import{createHash as Qj,randomUUID as Yj}from"node:crypto";import{createRequire as Vj}from"node:module";import{existsSync as A3,readFileSync as fY}from"node:fs";import{mkdir as hY,mkdtemp as Xj,readFile as IY,rename as gY,rm as y4,writeFile as mY}from"node:fs/promises";import{join as d0,isAbsolute as Hj}from"node:path";import{fileURLToPath as zj,pathToFileURL as Wj}from"node:url";function pY($,Z=G7){let J=d0(Z,$,"current.json");if(!A3(J))return null;let Q=JSON.parse(fY(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!Hj(Q.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Q}function O3($){let Z=pY($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!A3(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function U7($,Z){return Vj(d0(O3($),"package.json")).resolve(Z)}function f4($,Z){let J=d0(O3($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!A3(J))throw Error(`${$} executable missing: ${J}`);return J}async function cY(){return import(Wj(U7("claude","@anthropic-ai/claude-agent-sdk")).href)}async function _j($,Z,J){let Q=new AbortController,Y=()=>Q.abort(J?.reason);if(J?.addEventListener("abort",Y,{once:!0}),J?.aborted)Y();let V=setTimeout(()=>Q.abort(Error("npm registry request timed out")),30000);try{let X=await X0(`${Bj}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Q.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let H=await X.json();if(H.name!==$||typeof H.version!=="string"||!H.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return H}finally{clearTimeout(V),J?.removeEventListener("abort",Y)}}async function jj($,Z){let J={};if($!=="dsh"){let X=await Promise.all(v4[$].map((H)=>Z(H,"latest")));for(let H of X)J[H.name]=H.version;return J}let Q=await Z("@deepseek-ai/dsh","latest"),Y=new Set(v4.dsh),V=new Set;while(Y.size){let X=[...Y].slice(0,12);for(let z of X)Y.delete(z),V.add(z);let H=await Promise.all(X.map((z)=>z===Q.name?Q:Z(z,Q.version)));for(let z of H){if(z.version!==Q.version)throw Error(`DSH release package mismatch: ${z.name}@${z.version}, expected ${Q.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))Y.add(W)}}return J}async function r$($,Z=process.platform){for(let J=0;;J++)try{return await $()}catch(Q){let Y=Q.code;if(Z!=="win32"||!["EPERM","EACCES","EBUSY","ENOTEMPTY"].includes(Y??"")||J>=5)throw Q;await new Promise((V)=>setTimeout(V,100*(J+1)))}}async function Lj($,Z){let J=d0($,`current-${Yj()}.json`),Q;try{await mY(J,JSON.stringify(Z)+`
50
+ `,{mode:384}),await r$(()=>gY(J,d0($,"current.json")))}catch(Y){throw Q=Y,Y}finally{try{await r$(()=>y4(J,{force:!0}))}catch(Y){if(Q)throw AggregateError([Q,Y],`${M2(Q)}; state temporary file cleanup failed: ${M2(Y)}`);throw Y}}}async function qj($,Z){let J=d0($,"update.lock"),Q=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await hY(J);try{await r$(async()=>l0(d0(J,"pid"),String(process.pid)))}catch(Y){try{await r$(()=>y4(J,{recursive:!0}))}catch(V){throw AggregateError([Y,V],`${M2(Y)}; runtime update lock cleanup failed: ${M2(V)}`)}throw Y}return()=>r$(()=>y4(J,{recursive:!0}))}catch(Y){if(Y.code!=="EEXIST")throw Y;try{let V=Number(await IY(d0(J,"pid"),"utf8"));if(!Number.isSafeInteger(V)||V<=0)throw Error(`Invalid runtime update lock: ${J}`);try{process.kill(V,0)}catch(X){if(X.code!=="ESRCH")throw X;await r$(()=>y4(J,{recursive:!0}));continue}}catch(V){if(V.code!=="ENOENT")throw V}if(Date.now()>=Q)throw Error(`Timed out waiting for runtime update lock: ${J}`);await new Promise((V)=>setTimeout(V,200))}}}async function N3($,Z={}){let J=Z.root??G7,Q=d0(J,$);await hY(Q,{recursive:!0,mode:448});let Y=await qj(Q,Z.signal),V,X,H=!1;try{let z=pY($,J);Z.report?.(`${$}: 检查 upstream latest`);let W=await jj($,Z.metadata??((q,P)=>_j(q,P,Z.signal)));Z.signal?.throwIfAborted();let G=JSON.parse(fY(zj(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=Qj("sha256").update(JSON.stringify({installFormat:2,versions:Object.entries(W).sort(),security:G,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),_=d0(Q,K);if(!A3(_)){V=await Xj(d0(Q,".install-")),await mY(d0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:W[v4[$][0]],private:!0,type:"module",dependencies:W,overrides:{...G,...$==="dsh"?W:{}}})+`
51
+ `,{mode:384}),await(Z.install??P7)(V,Z.signal);for(let[P,N]of Object.entries(W)){let D=JSON.parse(await IY(d0(V,"node_modules",P,"package.json"),"utf8"));if(D.version!==N)throw Error(`npm installed ${P}@${D.version}, expected ${N}`)}Z.signal?.throwIfAborted();let q=V;await r$(()=>gY(q,_)),V=void 0}let L={directory:_,versions:W,checkedAt:Date.now()},j=z?.directory===_;return await Lj(Q,L),Z.report?.(`${$}: ${v4[$][0]}@${W[v4[$][0]]}${j?" 已是 latest":" 已更新,新进程使用新版"}`),L}catch(z){throw X=z,H=z instanceof M3,z}finally{let z=[];if(V&&!H){let W=V;try{await r$(()=>y4(W,{recursive:!0}))}catch(G){z.push(G)}}try{await Y()}catch(W){z.push(W)}if(z.length){let W=X?[X,...z]:z;throw AggregateError(W,W.map(M2).join("; "))}}}function uY($,Z={}){let J=Gj.filter((Q)=>Z.enabled?.[Q]===!0).map((Q)=>{let Y=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??N3)(Q,{report:$,signal:Y.signal}).catch((H)=>$(`${Q} 自动更新未完成: ${M2(H)}`)).finally(()=>{V=void 0})},Kj);return X.unref(),()=>{clearInterval(X),Y.abort()}});return()=>{for(let Q of J)Q()}}var Gj,Kj=21600000,Bj="https://registry.npmjs.org",v4,M2=($)=>$ instanceof Error?$.message:String($);var A2=O(()=>{u0();V0();D7();x0();D7();Gj=["codex","claude","dsh"],v4={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 dY;var lY=O(()=>{dY={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 oY={};v$(oY,{writeClaudeGlmEnv:()=>aY,runSetup:()=>kj});import{execFileSync as Pj,spawn as T3}from"node:child_process";import{spawn as Dj}from"cross-spawn";import{existsSync as A7,mkdirSync as nY,readFileSync as Uj}from"node:fs";import{createInterface as Mj}from"node:readline/promises";import{dirname as Aj,join as O7}from"node:path";import{homedir as Oj}from"node:os";import{fileURLToPath as Nj}from"node:url";async function x1($,Z={}){while(!0){let J=Z.default?`${F.dim} [${Z.default}]${F.reset}`:"",Q=(await h4.question(`${F.cyan}? ${F.reset}${$}${J}
52
+ ${F.green}>${F.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${F.red}必填,请重新输入${F.reset}`);continue}return Q}}function Rj($){let Z="═".repeat(58);console.log(`
53
+ ${F.bold}${F.cyan}╔${Z}╗${F.reset}`),console.log(`${F.bold}${F.cyan}║ ${$.padEnd(54)} ║${F.reset}`),console.log(`${F.bold}${F.cyan}╚${Z}╝${F.reset}
54
+ `)}function R3($,Z,J){console.log(`
55
+ ${F.bold}${F.yellow}[${$}/${Z}] ${J}${F.reset}
56
+ `)}function M7($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function iY($){try{let Z=Pj($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function Tj($){return new Promise((Z)=>{let J=Dj($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Q)=>Z(Q===0)),J.on("error",()=>Z(!1))})}function Ej(){return process.env.CLAUDE_CONFIG_DIR||O7(Oj(),".claude")}async function xj($){let Z=await U2(D2,$),J=(z)=>{let W=z.match(/(\d+(?:\.\d+)?)/);return W?Number(W[1]):-1},Y=[...Z.filter((z)=>!/-Turbo|-Air/i.test(z))].sort((z,W)=>J(W)-J(z)),V=Y[0],X=Y[Y.length-1];if(!V)throw Error("GLM 模型目录中没有可用于 Claude Code slots 的模型");let H={ANTHROPIC_DEFAULT_OPUS_MODEL:`${V}[1m]`,ANTHROPIC_DEFAULT_SONNET_MODEL:`${V}[1m]`};if(X&&X!==V)H.ANTHROPIC_DEFAULT_HAIKU_MODEL=X;return H}async function aY($){try{let Z=Ej();nY(Z,{recursive:!0});let J=O7(Z,"settings.json"),Q={};if(A7(J)){let H=Uj(J,"utf8");try{let z=JSON.parse(H);if(!z||typeof z!=="object"||Array.isArray(z))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=z}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Y=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},V=await xj($),X={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:D2,API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"};return Object.assign(X,V),Q.env={...Y,...X},l0(J,JSON.stringify(Q,null,2)+`
57
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function Sj($){try{if(process.platform==="win32")T3(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")T3("open",[$],{detached:!0,stdio:"ignore"}).unref();else T3("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function Cj($,Z){try{let Q=await(await X0("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(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Q.code} msg=${Q.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function bj(){try{let $=Aj(Nj(import.meta.url)),Z=O7($,"lodestar.js");if(!A7(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=T3(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function kj(){if(!process.stdin.isTTY)console.error(`${F.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${F.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(A7(E0)){if(console.log(`${F.yellow}发现已有配置: ${E0}${F.reset}`),(await x1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),h4.close();return}}Rj("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(` ${F.dim}1) 确保 Claude Code CLI 已装好${F.reset}`),console.log(` ${F.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${F.reset}`),console.log(` ${F.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${F.reset}`),console.log(` ${F.dim}4) 工作目录, 自动启动 daemon${F.reset}`),console.log(),await h4.question(`${F.dim}按 Enter 开始 (Ctrl+C 退出)...${F.reset}`),R3(1,4,"准备 Claude Code CLI"),await N3("claude",{report:(G)=>console.log(G)}),console.log(`${F.green}✓ Claude Code / SDK 已更新${F.reset}: ${F.dim}${f4("claude","claude")}${F.reset}`),console.log(),console.log(`${F.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${F.reset}`),console.log(`${F.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${F.reset}`),R3(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${F.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${F.reset}`),console.log(` ${F.dim}此项可选,直接回车跳过;以后可在群内发送 glm-setup <api_key> 补配。${F.reset}`),console.log(` ${F.dim}使用本机 Claude Code 或 Codex 订阅不需要 GLM Key。此处填写智谱国内站 Key;Z.ai 请之后用 glm-setup 指定对应地址。${F.reset}`),console.log();while(!0){let G=await x1("GLM API key (直接回车跳过)",{});if(!G){console.log(`${F.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${F.reset}`);break}let K=await aY(G);if("path"in K){console.log(`${F.green}✓ GLM 路由已写入${F.reset}: ${F.dim}${K.path}${F.reset}`),console.log(`${F.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${F.reset}`);break}else console.log(`${F.red}✗ GLM 配置失败:${F.reset} ${K.error}`),console.log(`${F.dim}请按错误提示处理后重新输入;直接回车可跳过,之后用群命令补配。${F.reset}`)}if(console.log(),console.log(`${F.bold}Codex (可选第二后端)${F.reset}`),console.log(` ${F.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${F.reset}`),(await x1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await N3("codex",{report:(K)=>console.log(K)});let G=f4("codex","codex");if(iY(G))console.log(`${F.green}✓ Codex 已登录 ChatGPT${F.reset}`);else if(console.log(`${F.dim}启动 \`codex login\`...${F.reset}`),await Tj(G)&&iY(G))console.log(`${F.green}✓ Codex 已登录 ChatGPT${F.reset}`);else console.log(`${F.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${F.reset}`)}else console.log(`${F.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${F.reset}`);R3(3,4,"Feishu 自建应用");let Z="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${F.cyan}${Z}${F.reset}`),Sj(Z),console.log(`${F.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${F.reset}`),console.log(),console.log(`${F.bold}详细操作步骤:${F.reset}`),console.log(),console.log(` ${F.bold}① 创建应用${F.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${F.dim}Lodestar${F.reset}), logo 随意。`),console.log(),console.log(` ${F.bold}② 添加机器人能力${F.reset}`),console.log(` 左侧菜单 "${F.cyan}添加应用能力${F.reset}" → 找到 "机器人" → 点 "${F.bold}添加${F.reset}" 按钮。`),console.log(),console.log(` ${F.bold}③ 申请权限 (左侧 "${F.cyan}权限管理${F.reset}" → "${F.bold}批量导入/导出权限${F.reset}")${F.reset}`),console.log(` ${F.yellow}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${F.reset}`),console.log(JSON.stringify(dY,null,2)),console.log(` ${F.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${F.reset}`),console.log(` ${F.dim}清单包含以下用途;也可按名称逐项开通:${F.reset}`),console.log(` ${F.dim}账号与认证信息 (排障):${F.reset}`),console.log(` • ${F.bold}verification:verification_information:readonly${F.reset} ${F.dim}# 查看账号主体认证状态${F.reset}`),console.log(` • ${F.bold}tenant:tenant:readonly${F.reset} ${F.dim}# 查看租户基本信息${F.reset}`),console.log(` ${F.dim}消息类:${F.reset}`),console.log(` • ${F.bold}im:message:send_as_bot${F.reset} ${F.dim}# 以机器人身份发消息${F.reset}`),console.log(` • ${F.bold}im:message${F.reset} ${F.dim}# 接收/操作消息 (核心)${F.reset}`),console.log(` • ${F.bold}im:chat${F.reset} ${F.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${F.reset}`),console.log(` • ${F.bold}im:chat:create${F.reset} ${F.dim}# wt: 自动创建 worktree 群${F.reset}`),console.log(` • ${F.bold}im:chat:delete${F.reset} ${F.dim}# wt: 解散 worktree 群${F.reset}`),console.log(` • ${F.bold}im:chat.members:read${F.reset} ${F.dim}# wt: 判断发起人是否已在群内${F.reset}`),console.log(` • ${F.bold}im:chat.members:write_only${F.reset} ${F.dim}# wt: 把发起人拉进已有 worktree 群${F.reset}`),console.log(` • ${F.bold}im:resource${F.reset} ${F.dim}# 上传/下载附件 (图文双向)${F.reset}`),console.log(` • ${F.bold}im:message.urgent${F.reset} ${F.dim}# 加急推送 (锁屏通知 / Ask)${F.reset}`),console.log(` • ${F.bold}im:message.group_msg${F.reset} ${F.dim}# 敏感: 接收群里所有消息${F.reset}`),console.log(` ${F.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${F.reset}`),console.log(` ${F.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${F.reset}`),console.log(` • ${F.bold}im:message.group_at_msg:readonly${F.reset} ${F.dim}# 读 @ 机器人消息 (兜底)${F.reset}`),console.log(` ${F.dim}卡片类 (Card Kit):${F.reset}`),console.log(` • ${F.bold}cardkit:card:read${F.reset} ${F.dim}# 读卡片状态${F.reset}`),console.log(` • ${F.bold}cardkit:card:write${F.reset} ${F.dim}# 创建/更新卡片 (流式渲染核心)${F.reset}`),console.log(` ${F.dim}云空间交付 (权限预先开通,功能仍按群开启):${F.reset}`),console.log(` • ${F.bold}drive:drive${F.reset} ${F.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${F.reset}`),console.log(` • ${F.bold}drive:file:upload${F.reset} ${F.dim}# 文件夹改名接口单独要求此权限${F.reset}`),console.log(` ${F.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${F.reset}`),console.log(` ${F.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${F.reset}`),console.log(),console.log(` ${F.bold}④ 订阅事件 (左侧 "${F.cyan}事件与回调${F.reset}", 拆两个子页:)${F.reset}`),console.log(` ${F.dim}a)${F.reset} ${F.bold}事件配置${F.reset} 页:`),console.log(` ${F.yellow}• "订阅方式" → 选 "长连接" → 点保存${F.reset}`),console.log(` • 添加事件: ${F.bold}im.message.receive_v1${F.reset} ${F.dim}# 收群消息${F.reset}`),console.log(` ${F.dim}b)${F.reset} ${F.bold}回调配置${F.reset} 页:`),console.log(` ${F.yellow}• "订阅方式" → 选 "长连接" → 点保存${F.reset}`),console.log(` • 添加事件: ${F.bold}card.action.trigger${F.reset} ${F.dim}# 卡片按钮点击回调${F.reset}`),console.log(),console.log(` ${F.bold}⑤ 发布版本${F.reset}`),console.log(` 页面顶部 "${F.bold}创建版本${F.reset}" → 滚到底点 "${F.bold}保存${F.reset}" → 弹框点 "${F.bold}发布${F.reset}"。`),console.log(` ${F.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${F.reset}`),console.log(),console.log(` ${F.bold}⑥ 拿凭据${F.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${F.bold}App ID${F.reset} (${F.dim}cli_...${F.reset}) 和 ${F.bold}App Secret${F.reset}, 待会粘到下面。`),console.log(),console.log(` ${F.bold}⑦ 把机器人拉进群${F.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${F.yellow}群名要等于 projects_root 下的项目目录名${F.reset} (下一步设, 默认是用户主目录)。`),console.log();let J="",Q="";while(!0){J=await x1("App ID (以 cli_ 开头)",{required:!0}),Q=await x1("App Secret",{required:!0}),console.log(`${F.dim}测试中... (调 tenant_access_token endpoint)${F.reset}`);let G=await Cj(J,Q);if(G.ok){console.log(`${F.green}✓ Feishu 凭据测试通过${F.reset}`);break}if(console.log(`${F.red}✗ 测试失败:${F.reset} ${G.error}`),console.log(`${F.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${F.reset}`),console.log(),(await x1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${F.yellow}已取消, 配置未写盘。${F.reset}`),h4.close(),process.exit(1)}R3(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let Y=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",V=await x1("projects_root",{default:Y});nY(Y7,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${M7(J)}"`,`app_secret = "${M7(Q)}"`,"","[runtime]",`projects_root = "${M7(V)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];l0(E0,X.join(`
58
58
  `)),console.log(`
59
- ${P.green}${P.bold}✓ 配置已写入${P.reset}`),console.log(` ${P.cyan}${E0}${P.reset}`),console.log(`
60
- ${P.bold}启动 daemon...${P.reset}`);let H=Kj(),z=process.platform==="win32"?"\\":"/",G=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(H.pid)console.log(`${P.green}✓ daemon 已在后台启动${P.reset} (pid ${H.pid})`),console.log(),console.log(`${P.bold}最后一步: 在 Feishu 验证${P.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${P.cyan}${V}${z}<群名>${P.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${P.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${P.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${P.cyan}${G}${P.reset}`),console.log(),console.log(`${P.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${P.reset}`);else console.log(`${P.yellow}启动失败: ${H.error}${P.reset}`),console.log(`手动运行: ${P.cyan}lodestar-daemon${P.reset}`);console.log(),k4.close()}var P,k4;var hQ=O(()=>{o0();x4();Q0();x0();L2();bQ();P={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},k4=Zj({input:process.stdin,output:process.stdout})});import{existsSync as _j,readFileSync as jj}from"node:fs";function IQ($,Z){return`${$}:${Z}`}function Lj(){if(!_j(Y3))return;try{let $=JSON.parse(jj(Y3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");y4=new Set($.ids)}catch($){_5=$ instanceof Error?$:Error(String($))}}function gQ(){if(_5)throw Error(`delegated-agent session registry is unavailable: ${_5.message}`)}function mQ($,Z){gQ();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=IQ($,J);if(y4.has(Y))return;let Q=new Set(y4);Q.add(Y),o(Y3,{version:1,ids:[...Q].sort()}),y4=Q}function P2($,Z){return gQ(),y4.has(IQ($,Z))}var y4,_5=null;var w4=O(()=>{Q0();x0();y4=new Set;Lj()});var pQ=1;import{appendFileSync as lQ,mkdirSync as Pj,readdirSync as qj,unlinkSync as dQ,existsSync as cQ,statSync as Fj,renameSync as Dj,readFileSync as Mj}from"node:fs";import{join as iQ}from"node:path";function P5($="development"){return $!=="test"}function nQ($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function aQ($,Z=t){return iQ(Z,`${j5}${nQ($)}${L5}`)}function Aj($){if(!$.startsWith(j5)||!$.endsWith(L5))return null;let Z=$.slice(j5.length,$.length-L5.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 oQ($,Z=new Date,J=Uj){let Y;try{Y=qj($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let X of Y){let H=Aj(X);if(!H)continue;if(Math.round((Q.getTime()-H.getTime())/86400000)<J)continue;try{dQ(iQ($,X)),V++}catch{}}return V}function Oj(){try{if(!cQ(H2))return;let $=Fj(H2);if(!$.isFile()||$.size===0)return;let Z=aQ($.mtime);if(cQ(Z)){lQ(Z,Mj(H2)),dQ(H2);return}Dj(H2,Z)}catch{}}function B($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
- `;if(process.stderr.write(J),!P5())return;try{let Y=nQ(Z);if(uQ!==Y)uQ=Y,oQ(t,Z);lQ(aQ(Z),J)}catch{}}var Uj=7,j5="daemon-",L5=".log",uQ=null;var f=O(()=>{Q0();if(P5())try{Pj(t,{recursive:!0})}catch{}if(P5()){Oj();try{oQ(t)}catch{}}});import{EventEmitter as Nj}from"node:events";import{createRequire as Rj}from"node:module";import{createHash as Tj,randomUUID as Ej}from"node:crypto";import{createInterface as xj}from"node:readline";import{dirname as Sj,join as C$,isAbsolute as Cj}from"node:path";import{fileURLToPath as q5}from"node:url";import{tmpdir as bj}from"node:os";import{existsSync as sQ,mkdirSync as tQ,mkdtempSync as kj,readFileSync as v4,renameSync as yj,writeFileSync as rQ,rmSync as F5}from"node:fs";import wj from"cross-spawn";function vj($){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 fj($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=v4(C$($,".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 X=V,H=X.type==="http"?{transport:"streamable-http",serverName:Q,url:X.url,headers:X.headers??{}}:X.type===void 0||X.type==="stdio"?{transport:"stdio",serverName:Q,command:X.command,args:X.args??[],env:X.env??{},cwd:$}:null;if(!H)throw Error(`DSH does not support MCP transport ${X.type} for ${Q}`);return{id:`lodestar-mcp-${Q}`,name:"@deepseek-ai/dsh-mcp-client",config:{...H,failOnStartupError:!0}}})}async function q2($,Z,J={}){let Y=new F3($);Y.on("failure",(X)=>B(`dsh catalog: ${X}`));let Q,V;try{await Y.initialize(),V=await Y.request(Z,J)}catch(X){Q=X}try{await Y.close()}catch(X){if(Q)throw AggregateError([Q,X],"DSH query and cleanup both failed");throw X}if(Q)throw Q;return V}var F3;var f4=O(()=>{Q0();L2();f();F3=class F3 extends Nj{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!Cj($.cwd))throw Error("DSH requires an absolute workspace");let Z=j3("dsh"),Y=Rj(C$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Q=JSON.parse(v4(Y,"utf8"));B(`dsh runtime: ${Q.version} (${Z})`);let V=vj($.env),X=$.home??G2;tQ(X,{recursive:!0,mode:448});let H=fj($.cwd,$.profile);this.launchDir=kj(C$(bj(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),G=z?"dsh-bridge.ts":"dsh-bridge.js",W=v4(q5(new URL(`./${G}`,import.meta.url))),K=z?v4(q5(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(v4(q5(new URL("../package.json",import.meta.url)),"utf8")),L=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),j=Tj("sha256").update(W).update(K).update(L).digest("hex").slice(0,20),q=C$(Z,".lodestar-bridges",j);tQ(q,{recursive:!0});let F=C$(q,G),R=(y,g)=>{if(sQ(y))return;let C=`${y}.${Ej()}.tmp`;try{rQ(C,g),yj(C,y)}finally{if(sQ(C))F5(C)}};if(R(C$(q,"package.json"),L),z)R(C$(q,"dsh-protocol.ts"),K);R(F,W);let D=[...["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:F},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...H]},...V],U=C$(this.launchDir,"bridge.patch.yml");rQ(U,JSON.stringify(D),{mode:384});let A=$.env.LODESTAR_DSH_NODE||"node",x=[C$(Sj(Y),Q.bin.dsh),"--profile","sdk","--patch",U,...($.patches??[]).flatMap((y)=>["--patch",y])],S={...$.env};if(S.LODESTAR_AGENT_CAPABILITY&&S.LODESTAR_AGENT_URL)S.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:S.LODESTAR_AGENT_URL,capability:S.LODESTAR_AGENT_CAPABILITY});for(let y of Object.keys(S))if(y.startsWith("LODESTAR_AGENT_"))delete S[y];try{this.child=wj(A,x,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...S,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(y){throw F5(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),B(`dsh stderr: ${y.trimEnd()}`)}),this.child.stdin.on("error",(y)=>this.transportFailure(y));let h=xj({input:this.child.stdout,crlfDelay:1/0});h.on("line",(y)=>this.receive(y)),this.exitTask=new Promise((y)=>{this.child.once("error",(g)=>this.transportFailure(g)),this.child.once("close",(g,C)=>{this.exited=!0,h.close();let I=Error(`DSH exited code=${g} signal=${C}
62
- ${this.stderr}`);this.rejectPending(I),F5(this.launchDir,{recursive:!0,force:!0}),y(),this.emit("exit",{code:g,signal:C,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==pQ||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 X=J===null?void 0:setTimeout(()=>{this.pending.delete(Y),V(Error(`DSH ${$} timed out after ${J}ms
63
- ${this.stderr}`))},J);this.pending.set(Y,{resolve:Q,reject:V,timer:X}),this.child.stdin.write(JSON.stringify({jsonrpc:"2.0",id:Y,method:$,params:Z})+`
64
- `,(H)=>{if(H)this.transportFailure(H)})})}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){B(`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){B(`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(B(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(B(`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 M$($){return typeof $==="string"&&D5.includes($)}function _0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function F0($){return typeof $==="string"&&M5.includes($)}function F2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function s0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var D5,M5,i$="max",D1,D2;var j0=O(()=>{D5=["codex","claude","dsh"];M5=["low","medium","high","xhigh","max","default"];D1=class D1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}};D2=class D2 extends Error{confirmedModel;constructor($,Z,J){super($,J);this.confirmedModel=Z;this.name="ModelSettingsUpdateError"}}});import{readFileSync as hj}from"node:fs";import{homedir as $V}from"node:os";function eQ($){return $.replace(/^~(?=\/|$)/,$V())}function Ij($){let Z={_:{}},J="_";for(let Y of $.split(`
65
- `)){let Q=gj(Y).trim();if(!Q)continue;let V=Q.match(/^\[([^\]]+)\]$/);if(V){J=V[1].trim(),Z[J]??={};continue}let X=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(X){let H=X[2].trim(),z=H.startsWith('"')&&H.endsWith('"'),G=H.startsWith("'")&&H.endsWith("'");if(z||G){if(H=H.slice(1,-1),z)H=H.replace(/\\([\\"])/g,"$1")}Z[J][X[1]]=H}}return Z}function gj($){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 h4(){let $;try{$=hj(E0,"utf8")}catch(A){throw process.stderr.write(`lodestar: cannot read config at ${E0}
59
+ ${F.green}${F.bold}✓ 配置已写入${F.reset}`),console.log(` ${F.cyan}${E0}${F.reset}`),console.log(`
60
+ ${F.bold}启动 daemon...${F.reset}`);let H=bj(),z=process.platform==="win32"?"\\":"/",W=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(H.pid)console.log(`${F.green}✓ daemon 已在后台启动${F.reset} (pid ${H.pid})`),console.log(),console.log(`${F.bold}最后一步: 在 Feishu 验证${F.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${F.cyan}${V}${z}<群名>${F.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${F.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${F.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${F.cyan}${W}${F.reset}`),console.log(),console.log(`${F.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${F.reset}`);else console.log(`${F.yellow}启动失败: ${H.error}${F.reset}`),console.log(`手动运行: ${F.cyan}lodestar-daemon${F.reset}`);console.log(),h4.close()}var F,h4;var sY=O(()=>{u0();w4();V0();x0();A2();lY();F={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},h4=Mj({input:process.stdin,output:process.stdout})});import{existsSync as wj,readFileSync as yj}from"node:fs";function tY($,Z){return`${$}:${Z}`}function vj(){if(!wj(B3))return;try{let $=JSON.parse(yj(B3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");I4=new Set($.ids)}catch($){N7=$ instanceof Error?$:Error(String($))}}function rY(){if(N7)throw Error(`delegated-agent session registry is unavailable: ${N7.message}`)}function eY($,Z){rY();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Q=tY($,J);if(I4.has(Q))return;let Y=new Set(I4);Y.add(Q),o(B3,{version:1,ids:[...Y].sort()}),I4=Y}function O2($,Z){return rY(),I4.has(tY($,Z))}var I4,N7=null;var g4=O(()=>{V0();x0();I4=new Set;vj()});var $V=1;import{appendFileSync as QV,mkdirSync as fj,readdirSync as hj,unlinkSync as YV,existsSync as ZV,statSync as Ij,renameSync as gj,readFileSync as mj}from"node:fs";import{join as VV}from"node:path";function E7($="development"){return $!=="test"}function XV($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function HV($,Z=t){return VV(Z,`${R7}${XV($)}${T7}`)}function cj($){if(!$.startsWith(R7)||!$.endsWith(T7))return null;let Z=$.slice(R7.length,$.length-T7.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Q=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Q.getTime())?null:Q}function zV($,Z=new Date,J=pj){let Q;try{Q=hj($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let X of Q){let H=cj(X);if(!H)continue;if(Math.round((Y.getTime()-H.getTime())/86400000)<J)continue;try{YV(VV($,X)),V++}catch{}}return V}function uj(){try{if(!ZV(j2))return;let $=Ij(j2);if(!$.isFile()||$.size===0)return;let Z=HV($.mtime);if(ZV(Z)){QV(Z,mj(j2)),YV(j2);return}gj(j2,Z)}catch{}}function B($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
61
+ `;if(process.stderr.write(J),!E7())return;try{let Q=XV(Z);if(JV!==Q)JV=Q,zV(t,Z);QV(HV(Z),J)}catch{}}var pj=7,R7="daemon-",T7=".log",JV=null;var h=O(()=>{V0();if(E7())try{fj(t,{recursive:!0})}catch{}if(E7()){uj();try{zV(t)}catch{}}});import{EventEmitter as lj}from"node:events";import{createRequire as dj}from"node:module";import{createHash as ij,randomUUID as nj}from"node:crypto";import{createInterface as aj}from"node:readline";import{dirname as oj,join as f$,isAbsolute as sj}from"node:path";import{fileURLToPath as x7}from"node:url";import{tmpdir as tj}from"node:os";import{existsSync as WV,mkdirSync as GV,mkdtempSync as rj,readFileSync as m4,renameSync as ej,writeFileSync as KV,rmSync as S7}from"node:fs";import $L from"cross-spawn";function ZL($){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((Q)=>typeof Q==="string"&&Q)))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((Q)=>({id:Q,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 JL($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=m4(f$($,".mcp.json"),"utf8")}catch(Y){if(Y?.code==="ENOENT")return[];throw Y}let Q=JSON.parse(J);if(!Q.mcpServers||typeof Q.mcpServers!=="object"||Array.isArray(Q.mcpServers))throw Error("DSH project .mcp.json must contain an mcpServers object");return Object.entries(Q.mcpServers).map(([Y,V])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Y)||!V||typeof V!=="object")throw Error(`invalid DSH MCP server: ${Y}`);let X=V,H=X.type==="http"?{transport:"streamable-http",serverName:Y,url:X.url,headers:X.headers??{}}:X.type===void 0||X.type==="stdio"?{transport:"stdio",serverName:Y,command:X.command,args:X.args??[],env:X.env??{},cwd:$}:null;if(!H)throw Error(`DSH does not support MCP transport ${X.type} for ${Y}`);return{id:`lodestar-mcp-${Y}`,name:"@deepseek-ai/dsh-mcp-client",config:{...H,failOnStartupError:!0}}})}async function N2($,Z,J={}){let Q=new E3($);Q.on("failure",(X)=>B(`dsh catalog: ${X}`));let Y,V;try{await Q.initialize(),V=await Q.request(Z,J)}catch(X){Y=X}try{await Q.close()}catch(X){if(Y)throw AggregateError([Y,X],"DSH query and cleanup both failed");throw X}if(Y)throw Y;return V}var E3;var p4=O(()=>{V0();A2();h();E3=class E3 extends lj{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!sj($.cwd))throw Error("DSH requires an absolute workspace");let Z=O3("dsh"),Q=dj(f$(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Y=JSON.parse(m4(Q,"utf8"));B(`dsh runtime: ${Y.version} (${Z})`);let V=ZL($.env),X=$.home??q2;GV(X,{recursive:!0,mode:448});let H=JL($.cwd,$.profile);this.launchDir=rj(f$(tj(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),W=z?"dsh-bridge.ts":"dsh-bridge.js",G=m4(x7(new URL(`./${W}`,import.meta.url))),K=z?m4(x7(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(m4(x7(new URL("../package.json",import.meta.url)),"utf8")),L=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),j=ij("sha256").update(G).update(K).update(L).digest("hex").slice(0,20),q=f$(Z,".lodestar-bridges",j);GV(q,{recursive:!0});let P=f$(q,W),N=(b,v)=>{if(WV(b))return;let C=`${b}.${nj()}.tmp`;try{KV(C,v),ej(C,b)}finally{if(WV(C))S7(C)}};if(N(f$(q,"package.json"),L),z)N(f$(q,"dsh-protocol.ts"),K);N(P,G);let D=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((b)=>({id:b,disabled:!0})),{id:"approval",config:{policy:"ask"}},{id:"permission",config:{defaultPreset:"lodestar",presets:{lodestar:{sandbox:"danger-full-access",approval:"ask"}}}},{id:"system-prompt",config:{personaPrefix:"You are a coding agent powered by {{model}}.",personaSuffix:"Your working directory is {{cwd}}."}},{id:"skill-filesystem",config:{includeDefaultRoots:!0,...$.managedSkillDir?{customSkillDirs:[$.managedSkillDir]}:{}}},{insert:[{id:"lodestar-bridge",name:P},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...H]},...V],U=f$(this.launchDir,"bridge.patch.yml");KV(U,JSON.stringify(D),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",T=[f$(oj(Q),Y.bin.dsh),"--profile","sdk","--patch",U,...($.patches??[]).flatMap((b)=>["--patch",b])],x={...$.env};if(x.LODESTAR_AGENT_CAPABILITY&&x.LODESTAR_AGENT_URL)x.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:x.LODESTAR_AGENT_URL,capability:x.LODESTAR_AGENT_CAPABILITY});for(let b of Object.keys(x))if(b.startsWith("LODESTAR_AGENT_"))delete x[b];try{this.child=$L(M,T,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...x,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(b){throw S7(this.launchDir,{recursive:!0,force:!0}),b}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(b)=>{this.stderr=(this.stderr+b).slice(-16384),B(`dsh stderr: ${b.trimEnd()}`)}),this.child.stdin.on("error",(b)=>this.transportFailure(b));let w=aj({input:this.child.stdout,crlfDelay:1/0});w.on("line",(b)=>this.receive(b)),this.exitTask=new Promise((b)=>{this.child.once("error",(v)=>this.transportFailure(v)),this.child.once("close",(v,C)=>{this.exited=!0,w.close();let f=Error(`DSH exited code=${v} signal=${C}
62
+ ${this.stderr}`);this.rejectPending(f),S7(this.launchDir,{recursive:!0,force:!0}),b(),this.emit("exit",{code:v,signal:C,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==$V||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 Q=++this.nextId;return new Promise((Y,V)=>{let X=J===null?void 0:setTimeout(()=>{this.pending.delete(Q),V(Error(`DSH ${$} timed out after ${J}ms
63
+ ${this.stderr}`))},J);this.pending.set(Q,{resolve:Y,reject:V,timer:X}),this.child.stdin.write(JSON.stringify({jsonrpc:"2.0",id:Q,method:$,params:Z})+`
64
+ `,(H)=>{if(H)this.transportFailure(H)})})}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){B(`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){B(`dsh shutdown: ${J}`)}this.child.stdin.end();let Z=async(J)=>{let Q;return await Promise.race([this.exitTask,new Promise((Y)=>{Q=setTimeout(Y,J)})]),clearTimeout(Q),this.exited};if(await Z($))return;if(B(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(B(`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 O$($){return typeof $==="string"&&C7.includes($)}function q0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function D0($){return typeof $==="string"&&c4.includes($)}function R2($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function y0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var C7,c4,e$="max",S1,T2;var G0=O(()=>{C7=["codex","claude","dsh"];c4=["low","medium","high","xhigh","max","default"];S1=class S1 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}};T2=class T2 extends Error{confirmedModel;constructor($,Z,J){super($,J);this.confirmedModel=Z;this.name="ModelSettingsUpdateError"}}});import{readFileSync as QL}from"node:fs";import{homedir as _V}from"node:os";function BV($){return $.replace(/^~(?=\/|$)/,_V())}function YL($){let Z={_:{}},J="_";for(let Q of $.split(`
65
+ `)){let Y=VL(Q).trim();if(!Y)continue;let V=Y.match(/^\[([^\]]+)\]$/);if(V){J=V[1].trim(),Z[J]??={};continue}let X=Y.match(/^([\w.-]+)\s*=\s*(.+)$/);if(X){let H=X[2].trim(),z=H.startsWith('"')&&H.endsWith('"'),W=H.startsWith("'")&&H.endsWith("'");if(z||W){if(H=H.slice(1,-1),z)H=H.replace(/\\([\\"])/g,"$1")}Z[J][X[1]]=H}}return Z}function VL($){let Z=null,J=!1;for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==="double"){if(J){J=!1;continue}if(Y==="\\"){J=!0;continue}if(Y==='"')Z=null;continue}if(Z==="single"){if(Y==="'")Z=null;continue}if(Y==='"')Z="double";else if(Y==="'")Z="single";else if(Y==="#")return $.slice(0,Q)}return $}function u4(){let $;try{$=QL(E0,"utf8")}catch(M){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
- `),A}let Z=Ij($),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=eQ(Z.runtime?.projects_root??$V()),V={codex:!1,claude:!1,dsh:!1},X=Z["runtime.agent_auto_update"],H=Z.runtime?.agent_auto_update;if(H!==void 0){if(X)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(H!=="true"&&H!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${H}"`);for(let A of["codex","claude","dsh"])V[A]=H==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
72
- `)}else if(X)for(let[A,x]of Object.entries(X)){if(A!=="codex"&&A!=="claude"&&A!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${A}"`);if(x!=="true"&&x!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${A} must be true or false, got "${x}"`);V[A]=x==="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 G=z,W=Z.notify?.bind??"127.0.0.1",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let _=Number.parseInt(K,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let L=(A)=>{let x=Z[A]??{},S={};for(let[h,y]of Object.entries(x))if(typeof y==="string"&&y.length>0)S[h]=y;return S},j=()=>{let A={};for(let[x,S]of Object.entries(Z)){if(!x.startsWith("claude.models."))continue;let y=x.slice(14).trim();if(!y)continue;let g={};for(let[C,I]of Object.entries(S)){if(typeof I!=="string"||I.length===0)continue;if(C.trim()==="model")g.model=I}A[y]=g}return A},q=()=>{let A={},x="projects.";for(let[S,h]of Object.entries(Z)){if(!S.startsWith("projects."))continue;let y=S.slice(9).trim();if(!y)continue;let g={};for(let[C,I]of Object.entries(h)){if(typeof I!=="string"||I.length===0)continue;switch(C.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}}A[y]=g}return A},F=()=>{let A={},x="token_source.";for(let[S,h]of Object.entries(Z)){if(!S.startsWith("token_source."))continue;let y=S.slice(13).trim();if(!y)continue;let g={};for(let[C,I]of Object.entries(h)){if(typeof I!=="string")continue;let c=C.trim();if(c==="enabled"){if(I!=="true"&&I!=="false")throw Error(`[${S}].enabled 必须为 true 或 false`);g.enabled=I==="true"}else if(c==="default")g.default=I==="true";else if(c==="agent"||c==="display"||c==="auth"||c==="base_url"||c==="auth_token"||c==="api_key"||c==="bin"||c==="model"||c==="effort"||c==="models"||c==="hidden_models"||c==="custom_models"||c==="slots"||c==="usage")g[c]=I}A[y]=g}return A},R=L("codex.env"),D=L("claude.env"),U=Z.claude?.bin?eQ(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:G,agent_auto_update:V},notify:{bind:W,port:_},codex:{env:R},claude:{bin:U,env:D,models:j()},projects:q(),token_sources:F()}}function ZV(){v.token_sources=h4().token_sources}var v;var S0=O(()=>{Q0();v=h4()});function K0($){return typeof $==="string"&&$?$:void 0}function n($){return $!=null&&typeof $==="object"?$:null}function b$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function D3($){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 pj($){let Z=$.slice(0,O5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function cj($){let Z=n($);if(!Z)return null;let J=n(Z.event),Y=n(Z.payload);return n(Z.item)??n(Z.responseItem)??n(Z.rawItem)??n(J?.item)??n(J?.responseItem)??n(J?.rawItem)??n(Y?.item)??n(Y?.responseItem)??n(Y?.rawItem)??(I4(Z.type)?Z:null)??(J&&I4(J.type)?J:null)??(Y&&I4(Y.type)?Y:null)}function uj($){let Z=[],J=new WeakSet,Y=(Q,V,X)=>{if(Z.length>=O5||X>6)return;if(Array.isArray(Q)){if(V)Z.push(`${V}[]`);if(Q.length>0)Y(Q[0],V?`${V}[]`:"[]",X+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let H of Object.keys(Q)){if(Z.length>=O5)return;let z=V?`${V}.${H}`:H;Z.push(z),Y(Q[H],z,X+1)}};return Y($,"",0),Z}function N5($){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>A5)return`${Q.slice(0,A5)}...<truncated ${Q.length-A5} 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>U5)return`${J.slice(0,U5)}...<truncated ${J.length-U5} chars>`;return J}function p0($,Z){let J=n(Z),Y=J?n(J.params):null,Q=J?n(J.item)??n(Y?.item):null,V=J?K0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${b$(V)}`,`rootKeys=${D3(J)}`,`itemKeys=${D3(Q)}`,`payload=${N5(Z)}`].join(" "))}function R5($,Z,J){let Y=n(Z),Q=cj(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(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${D3(Y)} itemKeys=${D3(Q)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${pj(uj(Z))}`),Q)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${N5(Q)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${N5(Z)}`)}function I4($){if(typeof $!=="string")return null;return mj.has($)?$:null}function lj($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||JV.has(Z))return"end";return"event"}function T5($,Z){return YV($,n(Z)??{})}function E5($){let Z=n($);if(!Z)return null;let J=K0(Z.method)??K0(Z.type)??"raw_message";return YV(J,Z)}function YV($,Z){let J=n(Z.payload),Y=[Z,n(Z.event),J,n(Z.item),n(Z.responseItem),n(Z.rawItem)].filter((z)=>z!=null),Q=null;for(let z of Y)if(Q=I4(z.type),Q)break;if(!JV.has($)&&!Q)return null;let V=n(Z.item)??n(Z.responseItem)??n(Z.rawItem),X=Q==="compacted"&&J?J:V&&I4(V.type)?V:Z,H=n(X.item)??n(X.responseItem)??n(X.rawItem)??V??{};return{...X,threadId:K0(X.threadId)??K0(X.thread_id)??K0(Z.threadId)??K0(Z.thread_id),turnId:K0(X.turnId)??K0(X.turn_id)??K0(Z.turnId)??K0(Z.turn_id),itemId:K0(X.itemId)??K0(X.item_id)??K0(H.id)??K0(H.itemId)??K0(H.item_id),timestamp:K0(Z.timestamp)??K0(X.timestamp),recordType:K0(Z.type),phase:lj(Q,$),sourceMethod:$,sourceType:Q??$}}var JV,mj,U5=200000,A5=50000,O5=400;var x5=O(()=>{f();JV=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),mj=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function g4($){return $!=null&&typeof $==="object"?$:null}function k$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function QV($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function M3($,Z){return $?k$($[Z]):void 0}function M2($){let Z=g4($);if(!Z)return null;let J=g4(Z.inputTokensDetails)??g4(Z.input_tokens_details),Y=g4(Z.outputTokensDetails)??g4(Z.output_tokens_details),Q={total_tokens:k$(Z.totalTokens??Z.total_tokens),input_tokens:k$(Z.inputTokens??Z.input_tokens),output_tokens:k$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:k$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??M3(Y,"reasoningTokens")??M3(Y,"reasoning_tokens")),cache_creation_input_tokens:k$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:k$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??M3(J,"cachedTokens")??M3(J,"cached_tokens"))};return QV(Q)?Q:null}function S5($,Z){let J=(Q)=>{let V=k$($?.[Q]),X=k$(Z?.[Q]);if(V===void 0&&X===void 0)return;return Math.max(0,(V??0)-(X??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 QV(Y)?Y:null}function C5($){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 VV($){let Z=$.trim();if(Z.length<2)return Z;let J=U3[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 k5($){let Z=ij(String($??"")),J=Z.split(`
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(`
71
+ `),M}let Z=YL($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${E0} is missing [feishu].app_id / [feishu].app_secret`);let Y=BV(Z.runtime?.projects_root??_V()),V={codex:!1,claude:!1,dsh:!1},X=Z["runtime.agent_auto_update"],H=Z.runtime?.agent_auto_update;if(H!==void 0){if(X)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(H!=="true"&&H!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${H}"`);for(let M of["codex","claude","dsh"])V[M]=H==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
72
+ `)}else if(X)for(let[M,T]of Object.entries(X)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(T!=="true"&&T!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${T}"`);V[M]=T==="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",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let _=Number.parseInt(K,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let L=(M)=>{let T=Z[M]??{},x={};for(let[w,b]of Object.entries(T))if(typeof b==="string"&&b.length>0)x[w]=b;return x},j=()=>{let M={};for(let[T,x]of Object.entries(Z)){if(!T.startsWith("claude.models."))continue;let b=T.slice(14).trim();if(!b)continue;let v={};for(let[C,f]of Object.entries(x)){if(typeof f!=="string"||f.length===0)continue;if(C.trim()==="model")v.model=f}M[b]=v}return M},q=()=>{let M={},T="projects.";for(let[x,w]of Object.entries(Z)){if(!x.startsWith("projects."))continue;let b=x.slice(9).trim();if(!b)continue;let v={};for(let[C,f]of Object.entries(w)){if(typeof f!=="string"||f.length===0)continue;switch(C.trim()){case"cwd":v.cwd=f;break;case"setting_sources":v.settingSources=f;break;case"strict_mcp":v.strictMcp=f==="true";break;case"tools":v.tools=f;break;case"load_project_mcp":v.loadProjectMcp=f==="true";break}}M[b]=v}return M},P=()=>{let M={},T="token_source.";for(let[x,w]of Object.entries(Z)){if(!x.startsWith("token_source."))continue;let b=x.slice(13).trim();if(!b)continue;let v={};for(let[C,f]of Object.entries(w)){if(typeof f!=="string")continue;let m=C.trim();if(m==="enabled"){if(f!=="true"&&f!=="false")throw Error(`[${x}].enabled 必须为 true 或 false`);v.enabled=f==="true"}else if(m==="default")v.default=f==="true";else if(m==="agent"||m==="display"||m==="auth"||m==="base_url"||m==="auth_token"||m==="api_key"||m==="management_token"||m==="management_user_id"||m==="management_url"||m==="billing_source"||m==="bin"||m==="model"||m==="effort"||m==="models"||m==="hidden_models"||m==="custom_models"||m==="slots"||m==="usage")v[m]=f}M[b]=v}return M},N=L("codex.env"),D=L("claude.env"),U=Z.claude?.bin?BV(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Q},runtime:{projects_root:Y,live_elapsed:W,agent_auto_update:V},notify:{bind:G,port:_},codex:{env:N},claude:{bin:U,env:D,models:j()},projects:q(),token_sources:P()}}function jV(){g.token_sources=u4().token_sources}var g;var S0=O(()=>{V0();g=u4()});function _0($){return typeof $==="string"&&$?$:void 0}function n($){return $!=null&&typeof $==="object"?$:null}function h$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function x3($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Q=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Q}]`}function HL($){let Z=$.slice(0,w7),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function zL($){let Z=n($);if(!Z)return null;let J=n(Z.event),Q=n(Z.payload);return n(Z.item)??n(Z.responseItem)??n(Z.rawItem)??n(J?.item)??n(J?.responseItem)??n(J?.rawItem)??n(Q?.item)??n(Q?.responseItem)??n(Q?.rawItem)??(l4(Z.type)?Z:null)??(J&&l4(J.type)?J:null)??(Q&&l4(Q.type)?Q:null)}function WL($){let Z=[],J=new WeakSet,Q=(Y,V,X)=>{if(Z.length>=w7||X>6)return;if(Array.isArray(Y)){if(V)Z.push(`${V}[]`);if(Y.length>0)Q(Y[0],V?`${V}[]`:"[]",X+1);return}if(Y==null||typeof Y!=="object")return;if(J.has(Y))return;J.add(Y);for(let H of Object.keys(Y)){if(Z.length>=w7)return;let z=V?`${V}.${H}`:H;Z.push(z),Q(Y[H],z,X+1)}};return Q($,"",0),Z}function y7($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Q,Y)=>{if(typeof Y==="bigint")return`${Y.toString()}n`;if(typeof Y==="string"&&Y.length>k7)return`${Y.slice(0,k7)}...<truncated ${Y.length-k7} chars>`;if(Y!=null&&typeof Y==="object"){if(Z.has(Y))return"[Circular]";Z.add(Y)}return Y})??String($)}catch(Q){J=`<unserializable: ${Q}>`}if(J.length>b7)return`${J.slice(0,b7)}...<truncated ${J.length-b7} chars>`;return J}function i0($,Z){let J=n(Z),Q=J?n(J.params):null,Y=J?n(J.item)??n(Q?.item):null,V=J?_0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${h$(V)}`,`rootKeys=${x3(J)}`,`itemKeys=${x3(Y)}`,`payload=${y7(Z)}`].join(" "))}function v7($,Z,J){let Q=n(Z),Y=zL(Z),V=[`phase=${h$(J.phase??"event")}`,`method=${h$($)}`,`sourceMethod=${h$(J.sourceMethod)}`,`sourceType=${h$(J.sourceType)}`,`sessionId=${h$(J.sessionId)}`,`threadId=${h$(J.threadId)}`,`turnId=${h$(J.turnId)}`,`itemId=${h$(J.itemId)}`].join(" ");if(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${x3(Q)} itemKeys=${x3(Y)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${HL(WL(Z))}`),Y)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${y7(Y)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${y7(Z)}`)}function l4($){if(typeof $!=="string")return null;return XL.has($)?$:null}function GL($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||LV.has(Z))return"end";return"event"}function f7($,Z){return qV($,n(Z)??{})}function h7($){let Z=n($);if(!Z)return null;let J=_0(Z.method)??_0(Z.type)??"raw_message";return qV(J,Z)}function qV($,Z){let J=n(Z.payload),Q=[Z,n(Z.event),J,n(Z.item),n(Z.responseItem),n(Z.rawItem)].filter((z)=>z!=null),Y=null;for(let z of Q)if(Y=l4(z.type),Y)break;if(!LV.has($)&&!Y)return null;let V=n(Z.item)??n(Z.responseItem)??n(Z.rawItem),X=Y==="compacted"&&J?J:V&&l4(V.type)?V:Z,H=n(X.item)??n(X.responseItem)??n(X.rawItem)??V??{};return{...X,threadId:_0(X.threadId)??_0(X.thread_id)??_0(Z.threadId)??_0(Z.thread_id),turnId:_0(X.turnId)??_0(X.turn_id)??_0(Z.turnId)??_0(Z.turn_id),itemId:_0(X.itemId)??_0(X.item_id)??_0(H.id)??_0(H.itemId)??_0(H.item_id),timestamp:_0(Z.timestamp)??_0(X.timestamp),recordType:_0(Z.type),phase:GL(Y,$),sourceMethod:$,sourceType:Y??$}}var LV,XL,b7=200000,k7=50000,w7=400;var I7=O(()=>{h();LV=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),XL=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function d4($){return $!=null&&typeof $==="object"?$:null}function I$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function FV($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function S3($,Z){return $?I$($[Z]):void 0}function E2($){let Z=d4($);if(!Z)return null;let J=d4(Z.inputTokensDetails)??d4(Z.input_tokens_details),Q=d4(Z.outputTokensDetails)??d4(Z.output_tokens_details),Y={total_tokens:I$(Z.totalTokens??Z.total_tokens),input_tokens:I$(Z.inputTokens??Z.input_tokens),output_tokens:I$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:I$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??S3(Q,"reasoningTokens")??S3(Q,"reasoning_tokens")),cache_creation_input_tokens:I$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:I$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??S3(J,"cachedTokens")??S3(J,"cached_tokens"))};return FV(Y)?Y:null}function g7($,Z){let J=(Y)=>{let V=I$($?.[Y]),X=I$(Z?.[Y]);if(V===void 0&&X===void 0)return;return Math.max(0,(V??0)-(X??0))},Q={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 FV(Q)?Q:null}function m7($){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 PV($){let Z=$.trim();if(Z.length<2)return Z;let J=C3[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/''/g,"'");if(Z[0]==='"')return Q.replace(/\\"/g,'"');return Q}function c7($){let Z=BL(String($??"")),J=Z.split(`
73
+ `,1)[0]?.trim()??"",Y=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),V=Y?Z.split(`
74
74
  `).slice(1).join(`
75
- `).trimStart():Z;return{description:Q,command:V||Z}}function U2($,Z=60){let{description:J,command:Y}=k5($);if(J)return J;return dj(Y).replace(/\s+/g," ").trim().slice(0,Z)}function dj($){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 ij($){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=aj(J[1]);return b5(Q||Z)}let Y=nj(Z);if(Y)return Y;return b5(Z)}function nj($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=VV(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 b5(VV(Q[2]));if(Y=Q[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function aj($){let Z=$.trim();if(Z.length<2)return Z;let J=U3[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 b5($){let Z=$.trim(),J=Z[0];if(!U3[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!oj(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,(X,H)=>` $(${H})`)}function oj($,Z){let J=U3[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 U3;var A3=O(()=>{U3={'"':'"',"'":"'","“":"”"}});function XV($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function N($){return $ instanceof Error?$.message:String($)}function O0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as HV}from"node:path";function sj($){return $.kind==="fresh"?null:$.source.provider}function L0($,Z,J){let Y=sj($);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"||!HV($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!HV(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 M1=()=>{};import{createHash as tj,randomUUID as zV}from"node:crypto";import{existsSync as O3,lstatSync as N3,mkdirSync as y5,readFileSync as GV,readdirSync as rj,realpathSync as A2,rmSync as ej,symlinkSync as $L,writeFileSync as ZL}from"node:fs";import{homedir as JL}from"node:os";import{isAbsolute as YL,join as y$,relative as QL,resolve as VL,sep as XL}from"node:path";class WV{defaultHome;root;stateFile;constructor($=VL(process.env.CODEX_HOME||y$(JL(),".codex")),Z=eY,J=$Q){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!O3(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(GV(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!==m&&!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:m,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(m);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(m);this.validateName($);let Z=this.read(),J=Z.accounts.find((Q)=>this.nameKey(Q.name)===this.nameKey($));if(J)return{...J};let Y={id:zV(),name:$.normalize("NFC").trim()};return Z.accounts.push(Y),o(this.stateFile,Z),Y}remove($){let Z=this.get($);if($===m)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(O2($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(T3($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Y=this.home($),Q;try{Q=N3(Y)}catch(X){if(X.code!=="ENOENT")throw X}if(Q){if(Q.isSymbolicLink()||!Q.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(O3(this.defaultHome)){let X=QL(A2(Y),A2(this.defaultHome));if(!X||!YL(X)&&X!==".."&&!X.startsWith(`..${XL}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{ej(Y,{recursive:!0})}catch(X){throw Error(`账号文件删除失败,账号记录已保留;${X}`)}}J.accounts=J.accounts.filter((X)=>X.id!==$);let V=0;for(let[X,H]of Object.entries(J.selections)){if(H!==$)continue;delete J.selections[X],V++}try{o(this.stateFile,J)}catch(X){throw Error(`账号文件已移除,但账号记录保存失败;请重试 codex-account-delete ${Z.name};${X}`)}return{account:Z,clearedSelections:V}}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:m}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],o(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),o(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==m){let Y=J.accounts.find((Q)=>Q.id===$);if(!Y)throw Error("登录完成时账号记录已不存在");Object.assign(Y,{email:Z.email,planType:Z.planType,revision:zV()}),o(this.stateFile,J)}}home($=m){return $===m?this.defaultHome:y$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===m)return Z;let J;try{J=N3(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(y5(Z,{recursive:!0,mode:448}),y5(this.defaultHome,{recursive:!0,mode:448}),A2(Z)===A2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Y;try{Y=N3(y$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Y?.isSymbolicLink()||Y&&!Y.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{ZL(y$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of HL){let X=y$(this.defaultHome,V);y5(X,{recursive:!0,mode:448}),this.link(X,y$(Z,V),!0)}let Q=new Set([...zL,...rj(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Q){let X=y$(this.defaultHome,V);if(O3(X))this.link(X,y$(Z,V),!1)}return Z}link($,Z,J){let Y;try{Y=N3(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q}if(Y){if(!Y.isSymbolicLink()||A2(Z)!==A2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}$L($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Y=!1){if(!Y&&O2($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Q=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Q};if($!==m){V.CODEX_SQLITE_HOME=Z.CODEX_SQLITE_HOME||this.defaultHome;for(let X of["CODEX_API_KEY","OPENAI_API_KEY","CODEX_ACCESS_TOKEN","OPENAI_FEDERATION_RULE_ID","OPENAI_IDENTITY_TOKEN_FILE","OPENAI_WORKLOAD_IDENTITY_CONTEXT"])delete V[X]}return V}cliArgs($){return this.get($),$===m?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=y$(this.home($),"auth.json");if(!O3(Z))return null;let Y=JSON.parse(GV(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 tj("sha256").update(JSON.stringify([Y.account_id,V.sub])).digest("hex")}}function n$($,Z,J=!0){if(KV.set($,Z),!R3.has($))$.once("exit",()=>R3.delete($));R3.set($,{id:Z,ownsNativeProcess:J})}function T3($,Z=!1){return[...R3].some(([J,Y])=>Y.id===$&&(Y.ownsNativeProcess||Z)&&J.isAlive())}function O2($){return m4.has($)}function BV($){if(m4.has($))throw Error("该账号已有登录任务");if(T3($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return m4.set($,Z),()=>{if(m4.get($)===Z)m4.delete($)}}function y0($){return $?KV.get($)??m:m}var m="default",HL,zL,k,KV,R3,m4;var w0=O(()=>{Q0();x0();HL=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],zL=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];k=new WV,KV=new WeakMap,R3=new Map;m4=new Map});function w5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function GL($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function p4($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$;return{...J,fiveHour:w5($.subscriptionType,J.fiveHour)}}function v5($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=p4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function f5($,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=GL($.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 X=p4($,Z),H=[X.fiveHour,X.weekly].filter((j)=>j!==null),z=H.filter((j)=>j.percent!==null&&j.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||X.rateLimitReachedType||X.spendControlReached===!0){let j=z.map((q)=>q.resetsAt?.getTime()).filter((q)=>q!=null&&Number.isFinite(q)&&q>J);return{...Q,state:"exhausted",reason:"额度耗尽",...j.length===z.length&&j.length?{retryAt:Math.max(...j)}:{}}}if(H.some((j)=>j.percent===null||!Number.isFinite(j.percent)||j.percent<0))return{...Q,reason:"额度百分比 MISS"};let G=X.weekly;if(!G||G.percent===null)return{...Q,reason:"周额度 MISS"};let W=G.resetsAt?.getTime();if(W==null||!Number.isFinite(W)||W<=J)return{...Q,reason:"周重置时间 MISS 或已过期"};let K=V*(100-G.percent)/100,_=(W-J)/3600000,L=K/_;if(Y==="ultra"&&K<0.5)return{...Q,state:"waiting",remaining:K,hours:_,weeklyScore:L,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:W};if($.subscriptionType==="plus"){let j=X.fiveHour,q=0.15*(100-j.percent)/100,F=j.unreportedFull?5:((j.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(F)||F<=0)return{...Q,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:K,hours:_,weeklyScore:L,fiveHourRemaining:q,fiveHourHours:F,availableNow:Math.min(K,q),score:Math.min(L,q/F)}}return{state:"ready",shares:V,remaining:K,hours:_,weeklyScore:L,availableNow:K,score:L}}function E3($){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 WL,existsSync as KL,mkdirSync as BL,openSync as _L,readdirSync as jL,readSync as LL,statSync as S3,writeFileSync as PL}from"node:fs";import{homedir as h5}from"node:os";import{delimiter as _V,isAbsolute as jV,join as a$}from"node:path";import{EventEmitter as qL}from"node:events";import{StringDecoder as LV}from"node:string_decoder";import{spawn as FL}from"cross-spawn";function c4(){return b4("codex","codex")}function DL(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([a$(h5(),".local","npm-global","bin"),a$(h5(),".local","bin"),a$(h5(),".bun","bin"),...(process.env.PATH??"").split(_V),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(_V)}function qV($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function TL($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function EL($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function t0($){return typeof $==="string"&&m5.includes($)}function xL($){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(!t0(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 I5($,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:g5($)}}return null}function SL($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function g5($){return{status:$.status,revisedPrompt:SL($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function FV($){if(!$||!KL(PV))return null;let Z=null,J=[PV];while(J.length){let Y=J.pop(),Q;try{Q=jL(Y,{withFileTypes:!0})}catch(V){B(`codex-process: cannot scan Codex session dir ${Y}: ${V instanceof Error?V.message:V}`);continue}for(let V of Q){let X=a$(Y,V.name);if(V.isDirectory()){J.push(X);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let H=S3(X).mtimeMs;if(!Z||H>Z.mtimeMs)Z={path:X,mtimeMs:H}}catch(H){B(`codex-process: cannot stat Codex rollout ${X}: ${H instanceof Error?H.message:H}`)}}}return Z?.path??null}function AV($,Z,J=ML){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let V=CL($,Z,J);if(V)return V;if(Q.length>2048){let X=OV($);return B(`codex-process: image generation inline result could not be decoded id=${X} 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 CL($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=bL(Y);if(!Q)return null;let V=DV(Z??"unknown-thread"),X=DV(OV($)),H=a$(J,V),z=a$(H,`${X}.${Q.ext}`);try{return BL(H,{recursive:!0}),PL(z,Q.buffer),z}catch(G){return B(`codex-process: failed to write image generation result ${z}: ${G instanceof Error?G.message:G}`),null}}function OV($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function DV($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function bL($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=yL(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,"="),X;try{X=Buffer.from(V,"base64")}catch{return null}if(X.length<12)return null;let H=kL(X)??Y;if(!H)return null;return{buffer:X,ext:H}}function kL($){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 yL($){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 MV($,Z,J){let Y=I5($,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:AV($,J),isError:$.status==="failed"}}return null}function x3($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return O0(Z)}function UV($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function wL($,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 U2(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 NV($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function vL($){let Z=NV($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function fL($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let V=Q,X=typeof V?.status==="string"?V.status:"unknown";J.push(`${O0(Y)}: ${X}`)}return J.join(`
79
- `)}var PV,ML,UL=30000,AL=600000,OL=5000,NL=60000,RL="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",m5,u4="xhigh",N2,R2;var U1=O(()=>{S0();f();L2();x5();A3();M1();w4();w0();x5();PV=a$(k.defaultHome,"sessions"),ML=a$(k.defaultHome,"generated_images");m5=["none","minimal","low","medium","high","xhigh","max","ultra"];N2=class N2 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"}};R2=class R2 extends qL{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 LV("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=c4(),J=[...TL($.allowDelegation!==!1),...k.cliArgs($.codexAccountId??m)];B(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:DL(),...v.codex.env,...$.hostEnv??{}},Q=k.env($.codexAccountId??m,$.transformEnv?$.transformEnv(Y):Y);this.proc=FL(Z,J,EL($.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,X)=>this.handleChildExit(V,X)),this.proc.on("close",(V,X)=>this.handleChildClose(V,X)),this.proc.on("error",(V)=>this.handleChildProcessError(V)),n$(this,$.codexAccountId??m)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(B(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){B(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,B(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((V,X)=>Error(`codex app-server closed before ${X.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($){B(`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)B(`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(),B(`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
- `))>=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){B(`codex-process: bad json: ${J.slice(0,200)} (${Q})`);continue}try{this.handleMessage(Y)}catch(Q){B(`codex-process: dispatch error: ${JSON.stringify(Y).slice(0,200)} (${Q})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
75
+ `).trimStart():Z;return{description:Y,command:V||Z}}function x2($,Z=60){let{description:J,command:Q}=c7($);if(J)return J;return KL(Q).replace(/\s+/g," ").trim().slice(0,Z)}function KL($){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 BL($){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 Y=jL(J[1]);return p7(Y||Z)}let Q=_L(Z);if(Q)return Q;return p7(Z)}function _L($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=PV(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Q=Z[2];for(;;){let Y=Q.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Y)break;let V=Y[1].toLowerCase();if(V==="-command"||V==="-c")return p7(PV(Y[2]));if(Q=Y[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function jL($){let Z=$.trim();if(Z.length<2)return Z;let J=C3[Z[0]];if(!J||!Z.endsWith(J))return Z;let Q=Z.slice(1,-1);if(Z[0]==="'")return Q.replace(/'\\''/g,"'");return Q.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
77
+ `)}function p7($){let Z=$.trim(),J=Z[0];if(!C3[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!LL(Q,J))return Z;if(J!=='"')return Q.replace(/'\s*$/,"");return Q.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
78
+ `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(X,H)=>` $(${H})`)}function LL($,Z){let J=C3[Z];for(let Q=0;Q<$.length;Q++){let Y=$[Q];if(Z==='"'&&Y==="\\"&&Q+1<$.length){Q++;continue}if(Y===J)return/^[\s]*$/.test($.slice(Q+1))}return!1}var C3;var b3=O(()=>{C3={'"':'"',"'":"'","“":"”"}});function DV($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function R($){return $ instanceof Error?$.message:String($)}function O0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as UV}from"node:path";function qL($){return $.kind==="fresh"?null:$.source.provider}function F0($,Z,J){let Q=qL($);if(Q&&Q!==Z)throw Error(`conversation launch provider mismatch: source=${Q} 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"||!UV($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!UV(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 C1=()=>{};import{createHash as FL,randomUUID as MV}from"node:crypto";import{existsSync as k3,lstatSync as w3,mkdirSync as u7,readFileSync as AV,readdirSync as PL,realpathSync as S2,rmSync as DL,symlinkSync as UL,writeFileSync as ML}from"node:fs";import{homedir as AL}from"node:os";import{isAbsolute as OL,join as g$,relative as NL,resolve as RL,sep as TL}from"node:path";class OV{defaultHome;root;stateFile;constructor($=RL(process.env.CODEX_HOME||g$(AL(),".codex")),Z=BY,J=_Y){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!k3(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(AV(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 Q of $.accounts){if(!Q||!/^[a-f0-9-]{36}$/.test(Q.id)||typeof Q.name!=="string"||Z.has(Q.id)||J.has(this.nameKey(Q.name)))throw Error("Codex 账号记录重复或无效");this.validateName(Q.name),Z.add(Q.id),J.add(this.nameKey(Q.name))}for(let Q of Object.values($.selections))if(Q!==p&&!Z.has(Q))throw Error("Codex 账号选择指向不存在的账号");return $}nameKey($){return $.normalize("NFC").trim().toLowerCase()}validateName($){if(!$.trim()||$.length>80||/[\x00-\x1f\x7f/\\]/.test($)||["default","默认",".",".."].includes(this.nameKey($)))throw Error("备注名须为 1–80 个字符,不能包含换行或路径分隔符;default/默认为保留名称")}list(){return[{id:p,name:"默认"},...this.read().accounts.map(($)=>({...$}))]}get($){let Z=this.list().find((J)=>J.id===$);if(!Z)throw Error(`Codex 账号不存在:${$}`);return Z}find($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(p);let Z=this.list().find((J)=>this.nameKey(J.name)===this.nameKey($));if(!Z)throw Error(`Codex 账号不存在:${$};先发送 codex-login ${$}`);return Z}ensure($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(p);this.validateName($);let Z=this.read(),J=Z.accounts.find((Y)=>this.nameKey(Y.name)===this.nameKey($));if(J)return{...J};let Q={id:MV(),name:$.normalize("NFC").trim()};return Z.accounts.push(Q),o(this.stateFile,Z),Q}remove($){let Z=this.get($);if($===p)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(C2($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(v3($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Q=this.home($),Y;try{Y=w3(Q)}catch(X){if(X.code!=="ENOENT")throw X}if(Y){if(Y.isSymbolicLink()||!Y.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(k3(this.defaultHome)){let X=NL(S2(Q),S2(this.defaultHome));if(!X||!OL(X)&&X!==".."&&!X.startsWith(`..${TL}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{DL(Q,{recursive:!0})}catch(X){throw Error(`账号文件删除失败,账号记录已保留;${X}`)}}J.accounts=J.accounts.filter((X)=>X.id!==$);let V=0;for(let[X,H]of Object.entries(J.selections)){if(H!==$)continue;delete J.selections[X],V++}try{o(this.stateFile,J)}catch(X){throw Error(`账号文件已移除,但账号记录保存失败;请重试 codex-account-delete ${Z.name};${X}`)}return{account:Z,clearedSelections:V}}selected($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:p}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],o(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),o(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($!==p){let Q=J.accounts.find((Y)=>Y.id===$);if(!Q)throw Error("登录完成时账号记录已不存在");Object.assign(Q,{email:Z.email,planType:Z.planType,revision:MV()}),o(this.stateFile,J)}}home($=p){return $===p?this.defaultHome:g$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===p)return Z;let J;try{J=w3(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(u7(Z,{recursive:!0,mode:448}),u7(this.defaultHome,{recursive:!0,mode:448}),S2(Z)===S2(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Q;try{Q=w3(g$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Q?.isSymbolicLink()||Q&&!Q.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{ML(g$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of EL){let X=g$(this.defaultHome,V);u7(X,{recursive:!0,mode:448}),this.link(X,g$(Z,V),!0)}let Y=new Set([...xL,...PL(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Y){let X=g$(this.defaultHome,V);if(k3(X))this.link(X,g$(Z,V),!1)}return Z}link($,Z,J){let Q;try{Q=w3(Z)}catch(Y){if(Y.code!=="ENOENT")throw Y}if(Q){if(!Q.isSymbolicLink()||S2(Z)!==S2($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}UL($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Q=!1){if(!Q&&C2($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Y=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Y};if($!==p){V.CODEX_SQLITE_HOME=Z.CODEX_SQLITE_HOME||this.defaultHome;for(let X of["CODEX_API_KEY","OPENAI_API_KEY","CODEX_ACCESS_TOKEN","OPENAI_FEDERATION_RULE_ID","OPENAI_IDENTITY_TOKEN_FILE","OPENAI_WORKLOAD_IDENTITY_CONTEXT"])delete V[X]}return V}cliArgs($){return this.get($),$===p?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=g$(this.home($),"auth.json");if(!k3(Z))return null;let Q=JSON.parse(AV(Z,"utf8"))?.tokens;if(!Q?.account_id||typeof Q.id_token!=="string")return null;let Y=Q.id_token.split(".")[1];if(!Y)throw Error("Codex 身份 Token 格式无效");let V=JSON.parse(Buffer.from(Y,"base64url").toString("utf8"));if(typeof V.sub!=="string"||!V.sub)return null;return FL("sha256").update(JSON.stringify([Q.account_id,V.sub])).digest("hex")}}function $1($,Z,J=!0){if(NV.set($,Z),!y3.has($))$.once("exit",()=>y3.delete($));y3.set($,{id:Z,ownsNativeProcess:J})}function v3($,Z=!1){return[...y3].some(([J,Q])=>Q.id===$&&(Q.ownsNativeProcess||Z)&&J.isAlive())}function C2($){return i4.has($)}function RV($){if(i4.has($))throw Error("该账号已有登录任务");if(v3($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return i4.set($,Z),()=>{if(i4.get($)===Z)i4.delete($)}}function v0($){return $?NV.get($)??p:p}var p="default",EL,xL,y,NV,y3,i4;var f0=O(()=>{V0();x0();EL=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],xL=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];y=new OV,NV=new WeakMap,y3=new Map;i4=new Map});function l7($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function SL($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function n4($,Z){let J=$.buckets?.find((Q)=>Q.limitName?.toLowerCase()===Z.toLowerCase()||Q.normalModelSlug===Z)??$;return{...J,fiveHour:l7($.subscriptionType,J.fiveHour)}}function d7($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=n4($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function i7($,Z,J=Date.now(),Q){let Y={state:"miss",score:null,shares:null,remaining:null,hours:null};if($.state!=="ok")return{...Y,reason:$.state==="network"?$.reason??"额度读取失败":$.state};let V=SL($.subscriptionType);if(V===null)return{...Y,reason:`未知周额度套餐:${$.subscriptionType??"MISS"}`};if(Y.shares=V,Q==="ultra"&&$.subscriptionType==="plus")return{...Y,state:"excluded",reason:"Ultra 自动选择不使用 Plus"};let X=n4($,Z),H=[X.fiveHour,X.weekly].filter((j)=>j!==null),z=H.filter((j)=>j.percent!==null&&j.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||X.rateLimitReachedType||X.spendControlReached===!0){let j=z.map((q)=>q.resetsAt?.getTime()).filter((q)=>q!=null&&Number.isFinite(q)&&q>J);return{...Y,state:"exhausted",reason:"额度耗尽",...j.length===z.length&&j.length?{retryAt:Math.max(...j)}:{}}}if(H.some((j)=>j.percent===null||!Number.isFinite(j.percent)||j.percent<0))return{...Y,reason:"额度百分比 MISS"};let W=X.weekly;if(!W||W.percent===null)return{...Y,reason:"周额度 MISS"};let G=W.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Y,reason:"周重置时间 MISS 或已过期"};let K=V*(100-W.percent)/100,_=(G-J)/3600000,L=K/_;if(Q==="ultra"&&K<0.5)return{...Y,state:"waiting",remaining:K,hours:_,weeklyScore:L,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:G};if($.subscriptionType==="plus"){let j=X.fiveHour,q=0.15*(100-j.percent)/100,P=j.unreportedFull?5:((j.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(P)||P<=0)return{...Y,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:K,hours:_,weeklyScore:L,fiveHourRemaining:q,fiveHourHours:P,availableNow:Math.min(K,q),score:Math.min(L,q/P)}}return{state:"ready",shares:V,remaining:K,hours:_,weeklyScore:L,availableNow:K,score:L}}function f3($){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 CL,existsSync as bL,mkdirSync as kL,openSync as wL,readdirSync as yL,readSync as vL,statSync as I3,writeFileSync as fL}from"node:fs";import{homedir as n7}from"node:os";import{delimiter as TV,isAbsolute as EV,join as Z1}from"node:path";import{EventEmitter as hL}from"node:events";import{StringDecoder as xV}from"node:string_decoder";import{spawn as IL}from"cross-spawn";function a4(){return f4("codex","codex")}function gL(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([Z1(n7(),".local","npm-global","bin"),Z1(n7(),".local","bin"),Z1(n7(),".bun","bin"),...(process.env.PATH??"").split(TV),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(TV)}function CV($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function iL($){if(!/^[a-z][a-z0-9_-]*$/.test($.id)||["openai","ollama","lmstudio"].includes($.id))throw Error("Codex API provider id 无效或属于保留名称");if(!/^[A-Z][A-Z0-9_]*$/.test($.envKey))throw Error("Codex API key 环境变量名无效");let Z=`model_providers.${$.id}`,J={name:$.name,base_url:$.baseUrl,env_key:$.envKey,wire_api:"responses",requires_openai_auth:!1,supports_websockets:!1},Q=`{${Object.entries(J).map(([Y,V])=>`${Y}=${JSON.stringify(V)}`).join(",")}}`;return["-c",`model_provider=${JSON.stringify($.id)}`,"-c",`${Z}=${Q}`,"-c","features.apps=false"]}function nL($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function aL($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function Z$($){return typeof $==="string"&&o4.includes($)}function oL($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Q of $){let Y=typeof Q==="string"?Q:typeof Q==="object"&&Q?Q.reasoningEffort:null;if(!Z$(Y)||Z.has(Y))continue;Z.add(Y);let V=typeof Q==="object"&&Q&&typeof Q.description==="string"?Q.description:"";J.push({reasoningEffort:Y,description:V})}return J}function a7($,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:o7($)}}return null}function sL($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function o7($){return{status:$.status,revisedPrompt:sL($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function bV($){if(!$||!bL(SV))return null;let Z=null,J=[SV];while(J.length){let Q=J.pop(),Y;try{Y=yL(Q,{withFileTypes:!0})}catch(V){B(`codex-process: cannot scan Codex session dir ${Q}: ${V instanceof Error?V.message:V}`);continue}for(let V of Y){let X=Z1(Q,V.name);if(V.isDirectory()){J.push(X);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let H=I3(X).mtimeMs;if(!Z||H>Z.mtimeMs)Z={path:X,mtimeMs:H}}catch(H){B(`codex-process: cannot stat Codex rollout ${X}: ${H instanceof Error?H.message:H}`)}}}return Z?.path??null}function vV($,Z,J=mL){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let V=tL($,Z,J);if(V)return V;if(Y.length>2048){let X=fV($);return B(`codex-process: image generation inline result could not be decoded id=${X} length=${Y.length}`),`Image generation returned ${Y.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Y}if(Y&&typeof Y==="object"){let V=Y.savedPath??Y.saved_path??Y.path;if(typeof V==="string"&&V)return V;return JSON.stringify(Y,null,2)}return""}function tL($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=rL(Q);if(!Y)return null;let V=kV(Z??"unknown-thread"),X=kV(fV($)),H=Z1(J,V),z=Z1(H,`${X}.${Y.ext}`);try{return kL(H,{recursive:!0}),fL(z,Y.buffer),z}catch(W){return B(`codex-process: failed to write image generation result ${z}: ${W instanceof Error?W.message:W}`),null}}function fV($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function kV($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function rL($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=$q(Y[1]),J=Y[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,"="),X;try{X=Buffer.from(V,"base64")}catch{return null}if(X.length<12)return null;let H=eL(X)??Q;if(!H)return null;return{buffer:X,ext:H}}function eL($){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 $q($){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 wV($,Z,J){let Q=a7($,Z);if(!Q)return null;switch($.type){case"commandExecution":return{...Q,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Q,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Q,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Q,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Q,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Q,output:vV($,J),isError:$.status==="failed"}}return null}function h3($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return O0(Z)}function yV($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function Zq($,Z,J){let Q=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return x2(Q(Z?.command))||"(空命令)"}case"FileChange":{let Y=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Y>0?`改 ${Y} 个文件`:"文件变更"}case"MCP":return`${Q(Z?.server)}/${Q(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Q(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Y=J.replace(/\s+/g," ").trim();return Y?`→ ${Y.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function hV($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function Jq($){let Z=hV($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function Qq($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Q,Y]of Object.entries(Z)){let V=Y,X=typeof V?.status==="string"?V.status:"unknown";J.push(`${O0(Q)}: ${X}`)}return J.join(`
79
+ `)}var SV,mL,pL=30000,cL=600000,uL=5000,lL=60000,dL="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",o4,s4="xhigh",b2,k2;var J1=O(()=>{S0();h();A2();I7();b3();C1();g4();f0();I7();SV=Z1(y.defaultHome,"sessions"),mL=Z1(y.defaultHome,"generated_images");o4=["none","minimal","low","medium","high","xhigh","max","ultra"];b2=class b2 extends Error{method;requestId;serverCode;serverMessage;serverData;constructor($,Z,J,Q,Y){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Q}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Q;this.serverData=Y;this.name="CodexRpcResponseError"}};k2=class k2 extends hL{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 xV("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((X)=>{this.resolveExit=X}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=a4(),J=[...nL($.allowDelegation!==!1),...$.apiProvider?iL($.apiProvider):[...$.tokenSourceId==="codex-sub"?["-c",'model_provider="openai"']:[],...y.cliArgs($.codexAccountId??p)]];B(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:gL(),...g.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q,V=$.apiProvider?{...Y,CODEX_HOME:y.defaultHome}:y.env($.codexAccountId??p,Y);if(this.proc=IL(Z,J,aL($.workDir,V)),this.proc.stdout.on("data",(X)=>this.onStdout(X)),this.proc.stderr.on("data",(X)=>this.onStderr(X)),this.proc.stdin.on("error",(X)=>this.handleStdinError(X)),this.proc.on("exit",(X,H)=>this.handleChildExit(X,H)),this.proc.on("close",(X,H)=>this.handleChildClose(X,H)),this.proc.on("error",(X)=>this.handleChildProcessError(X)),!$.apiProvider)$1(this,$.codexAccountId??p)}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(B(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){B(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,B(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((V,X)=>Error(`codex app-server closed before ${X.method} response (id=${V})`)),this.serverRequests.clear();let J=$??this.childExitCode,Q=Z??this.childExitSignal,Y=this.conversationMaterializationBarrier();if(Y){Y.then(()=>this.emitProcessExit(J,Q),()=>this.emitProcessExit(J,Q));return}this.emitProcessExit(J,Q)}handleChildProcessError($){B(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Q,Y)=>Error(`codex app-server process failed before ${Y.method} response (id=${Q}): ${$.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)B(`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(),B(`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
+ `))>=0){let J=this.stdoutBuf.slice(0,Z).trim();if(this.stdoutBuf=this.stdoutBuf.slice(Z+1),!J)continue;let Q;try{Q=JSON.parse(J)}catch(Y){B(`codex-process: bad json: ${J.slice(0,200)} (${Y})`);continue}try{this.handleMessage(Q)}catch(Y){B(`codex-process: dispatch error: ${JSON.stringify(Q).slice(0,200)} (${Y})`)}}}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())B(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())B(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){B(`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 N2(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=E5($);if(Z){let J=this.withSessionId(Z);R5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}p0("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=T5($,Z);if(J){let Y=this.withSessionId(J);R5($,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(t0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=M2(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=M2(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){p0("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){p0("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)){B(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),B(`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 p0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Y.status,X=Y.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let H=V==="failed"||!!X,z=V==="completed"&&!H&&!!Q;if(this.lastCompletedTurnId=z?Q:null,this.currentTurnId=null,V==="failed"&&Q&&qV(X?.message)&&this.scheduleCapacityRetry(X.message,RL))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let G=H?X?.type??X?.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:G,is_error:H},this.emit("result",{subtype:G,is_error:H,...H&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Q&&E3(X)?{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 B("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 p0("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":{B(`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":{B(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{B(`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}}p0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){p0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=I5(Z,this.opts.workDir);if(!J){p0("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){p0("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=MV(Z,this.opts.workDir,this.sessionId??void 0);if(!J){p0("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:g5(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"?I5($,this.opts.workDir):MV($,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:wL(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=x3($.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=x3($.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=NV($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,x3(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:UV($.prompt),description:vL($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:fL($),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($)??x3(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 X={task_id:$,task_type:"local_agent",description:"子 agent",prompt:UV(J.prompt)};this.emit("bg_task_started",X);let H={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",H)}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 LV("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=FV(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=S3($).size,B(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){B(`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??FV(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=S3($).size;if(Q<=this.rolloutReadOffset)return;let V=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=_L($,"r"),H=0;try{while(H<V){let z=LL(X,Z,H,V-H,this.rolloutReadOffset+H);if(z===0)break;H+=z}}finally{WL(X)}Z=Z.subarray(0,H),this.rolloutReadOffset+=H}catch(Q){B(`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){B(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let X=V?.payload,H=X?.type;if(H!=="image_generation_end"&&H!=="image_generation_call")continue;this.emitRolloutImageGeneration(X)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=AV($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&jV(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:g5({...$,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:p0("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 B(`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=UL){let Y=++this.requestCounter;return new Promise((Q,V)=>{let X=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)),H={resolve:Q,reject:V,method:$,timeout:X};this.pending.set(Y,H),this.write({id:Y,method:$,params:Z},(z)=>{if(this.pending.get(Y)!==H)return;this.pending.delete(Y),clearTimeout(X),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(($)=>{B(`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 X=typeof Q.path==="string"&&Q.path?Q.path:null;if(!X||!jV(X)||!X.endsWith(`${Q.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${X??"MISS"}`);if(this.sessionId=Q.id,this.conversationRolloutPath=X,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Y?.model)this.lastModel=Y.model;if(t0(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;B(`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,B(`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,B(`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},AL))?.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=S3(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(L0($,"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())B(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())B(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){B(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Q=typeof $.error?.code==="number"?$.error.code:null,Y=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new b2(J.method,$.id,Q,Y,$.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=h7($);if(Z){let J=this.withSessionId(Z);v7(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}i0("RAW_MESSAGE",$),this.emit("raw",$)}handleNotification($,Z){if(this.isSubagentThread(Z)){if($==="thread/status/changed")this.handleThreadStatusChanged(Z);else if($==="item/started")this.handleSubagentItemStarted(Z);else if($==="item/completed")this.handleSubagentItemCompleted(Z);return}let J=f7($,Z);if(J){let Q=this.withSessionId(J);v7($,Z,Q),this.emit("context_compacted",Q);return}switch($){case"thread/started":{let Q=Z.thread;if(Q?.id)this.sessionId=Q.id;return}case"thread/settings/updated":{let Q=Z.threadSettings;if(typeof Q?.model==="string")this.lastModel=Q.model;if(Z$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=E2(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=E2(Z.tokenUsage?.total);let Y=Z.tokenUsage?.modelContextWindow;if(typeof Y==="number"&&Y>0)this.lastContextWindow=Y;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){i0("TURN_STARTED_THREAD_MISMATCH",{method:$,params:Z});return}this.recordTurnStarted(Z.turn,Z.threadId,"turn/started notification"),this.markConversationMaterialized("turn/started notification");return}case"turn/completed":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){i0("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Q=Z.turn??{},Y=typeof Q.id==="string"&&Q.id?Q.id:null;if(Y){if(this.finishedTurnIds?.has(Y)){B(`codex-process: duplicate turn/completed ignored turn=${Y}`);return}if(this.currentTurnId&&this.currentTurnId!==Y){this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y),B(`codex-process: stale turn/completed ignored turn=${Y} current=${this.currentTurnId}`);return}this.flushRolloutImageGenerations(),this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Y),this.rememberFinishedTurn(Y)}else i0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Q.status,X=Q.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Y?this.turnError.error:null);this.turnError=null;let H=V==="failed"||!!X,z=V==="completed"&&!H&&!!Y;if(this.lastCompletedTurnId=z?Y:null,this.currentTurnId=null,V==="failed"&&Y&&CV(X?.message)&&this.scheduleCapacityRetry(X.message,dL))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let W=H?X?.type??X?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Q.durationMs==="number"?Q.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:W,is_error:H},this.emit("result",{subtype:W,is_error:H,...H&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Y&&f3(X)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:z&&this.sessionId?{provider:"codex",kind:"turn",id:Y,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 B("codex-process: thread/goal/updated missing goal");return}case"thread/goal/cleared":{this.emit("thread_goal_cleared",Z);return}case"thread/status/changed":{this.handleThreadStatusChanged(Z);return}case"item/agentMessage/delta":{if(typeof Z.delta==="string"&&Z.delta.length>0)this.emit("assistant_text",{uuid:Z.itemId,text:Z.delta,parentToolUseId:null});else i0("AGENT_MESSAGE_DELTA_EMPTY",{method:$,params:Z});return}case"item/started":{this.handleItemStarted(Z);return}case"item/completed":{this.handleItemCompleted(Z);return}case"mcpServer/startupStatus/updated":{B(`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":{B(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{B(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`);let Q=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:Q};this.emit("error",Error(Q.message??Q.summary??"codex app-server error"));return}}i0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){i0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=a7(Z,this.opts.workDir);if(!J){i0("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started"))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Q=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Q,J)}return}if(this.feedCollabItem(Z,"completed"))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){i0("ITEM_COMPLETED_MISSING_ID",{method:"item/completed",params:$});return}if(Z.type==="agentMessage"){this.lastAssistantUuid=Z.id,this.emit("assistant_block_stop",{index:Z.id,parentToolUseId:null});return}if(this.feedCollabItem(Z,"completed"))return;let J=wV(Z,this.opts.workDir,this.sessionId??void 0);if(!J){i0("ITEM_COMPLETED_UNMAPPED",{method:"item/completed",params:$});return}if(this.emit("tool_result",{tool_use_id:Z.id,content:J.output,is_error:J.isError,...Z.type==="imageGeneration"?{input:o7(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 Q=typeof J?.threadId==="string"?J.threadId:"",Y=Z==="started"?a7($,this.opts.workDir):wV($,this.opts.workDir,this.sessionId??void 0);if(!Y)return;let V="output"in Y&&typeof Y.output==="string"?Y.output:void 0;this.emit("subagent_step",{thread_id:Q,item_id:$.id,tool:Y.name,phase:Z,brief:Zq(Y.name,Y.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 Q=h3($.agentPath,J);this.collabAgentNames.set(J,Q),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Q}),this.emit("bg_task_updated",{task_id:J,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Q=this.collabAgentNames.get(J),Y=h3($.agentPath,J);if(Q!==Y&&!this.collabAgentSettled.has(J))this.collabAgentNames.set(J,Y),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Y})}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[Q,Y]of Object.entries(J))this.translateAgentState(Q,Y,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Q=hV($);for(let Y of Q){if(this.collabAgentSettled.has(Y))continue;if(this.collabAgentSettled.add(Y),!this.collabAgentNames.has(Y))this.collabAgentNames.set(Y,h3(null,Y));this.emit("bg_task_settled",{task_id:Y,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:yV($.prompt),description:Jq($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:Qq($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Q=Z?.status;if(typeof Q!=="string")return;if(this.collabAgentSettled.has($)){if(Q!=="running"&&Q!=="pendingInit"){if(Q==="errored"||Q==="shutdown"||Q==="notFound"||Q==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Q==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let V=this.collabAgentNames.get($)??h3(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 X={task_id:$,task_type:"local_agent",description:"子 agent",prompt:yV(J.prompt)};this.emit("bg_task_started",X);let H={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",H)}if(Q==="running"||Q==="pendingInit"||Q==="interrupted"){let V={task_id:$,patch:{status:Q==="pendingInit"?"pending":Q==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",V);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Y={task_id:$,status:Q==="completed"?"completed":Q==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Y)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new xV("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=bV(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=I3($).size,B(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){B(`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??bV(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=I3($).size;if(Y<=this.rolloutReadOffset)return;let V=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=wL($,"r"),H=0;try{while(H<V){let z=vL(X,Z,H,V-H,this.rolloutReadOffset+H);if(z===0)break;H+=z}}finally{CL(X)}Z=Z.subarray(0,H),this.rolloutReadOffset+=H}catch(Y){B(`codex-process: image generation rollout read failed ${$}: ${Y instanceof Error?Y.message:Y}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Q=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
83
+ `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let V;try{V=JSON.parse(Y)}catch(z){B(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let X=V?.payload,H=X?.type;if(H!=="image_generation_end"&&H!=="image_generation_call")continue;this.emitRolloutImageGeneration(X)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=vV($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&EV(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:o7({...$,status:Y})}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Q})}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??{},Q={questions:(J.questions??[]).map((Y)=>({id:Y.id,header:Y.header,question:Y.question,options:Array.isArray(Y.options)&&Y.options.length?Y.options.map((V)=>({label:V.label,description:V.description})):[{label:"自定义回答",description:Y.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Q}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Q,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:i0("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));return B(`codex-process: stdin write failed: ${Y.message}`),Z?.(Y),!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
+ `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=pL){let Q=++this.requestCounter;return new Promise((Y,V)=>{let X=setTimeout(()=>{let z=this.pending.get(Q);if(!z)return;this.pending.delete(Q),z.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),H={resolve:Y,reject:V,method:$,timeout:X};this.pending.set(Q,H),this.write({id:Q,method:$,params:Z},(z)=>{if(this.pending.get(Q)!==H)return;this.pending.delete(Q),clearTimeout(X),V(Error(`codex app-server ${$} request write failed (id=${Q}): ${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($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,result:Z})}respondError($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{B(`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,Q;if($.kind==="resume")J="thread/resume",Q=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Q=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Q=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Y=Q?.thread;if(typeof Y?.id!=="string"||!Y.id)throw Error(`codex app-server ${J} returned no thread.id`);let V=typeof Y.cwd==="string"?Y.cwd:typeof Q?.cwd==="string"?Q.cwd:null;if(V!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${V??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Y.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Y.id}`);if($.kind==="resume"&&Y.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Y.id}, expected ${$.source.sessionId}`);let X=typeof Y.path==="string"&&Y.path?Y.path:null;if(!X||!EV(X)||!X.endsWith(`${Y.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${X??"MISS"}`);if(this.sessionId=Y.id,this.conversationRolloutPath=X,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Q?.model)this.lastModel=Q.model;if(Z$(Q?.reasoningEffort))this.lastEffort=Q.reasoningEffort;else this.lastEffort=this.opts.effort??null;B(`codex-process: thread=${this.sessionId}`),this.primeRolloutImageGenerationScan(),this.emit("init",{session_id:this.sessionId,thread:Y})}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,B(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Q)=>{let Y=Q instanceof Error?Q:Error(String(Q));this.lastConversationMaterializationFailure=Y,B(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Y.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Y})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Q=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Q)this.markConversationMaterialized(Q)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Y=(await this.request("thread/read",{threadId:Z,includeTurns:!0},cL))?.thread;if(Y?.id!==Z||Y.cwd!==this.opts.workDir||Y.path!==J||!Array.isArray(Y.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=I3(Z)}catch(Q){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Q instanceof Error?Q.message:Q}`,{cause:Q})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(F0($,"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.apiProvider?{modelProvider:this.opts.apiProvider.id}:this.opts.tokenSourceId==="codex-sub"?{modelProvider:"openai"}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:this.opts.serviceName??"lodestar"}}sendUserText($,Z=[]){let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).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:xL(Y.supportedReasoningEfforts),defaultReasoningEffort:t0(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 X=typeof V.status==="string"?V.status:typeof V.status?.type==="string"?V.status.type:void 0;if(P2("codex",V.id))continue;$.push({provider:"codex",sessionId:V.id,cwd:V.cwd,preview:V.preview,ts:V.updatedAt*1000,...X?{status:X}:{}})}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){B("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)){B(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(B(`codex-process: turn/start failed: ${J}`),$ instanceof N2&&$.method==="turn/start"&&qV($.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 N2&&$.method==="turn/start"&&Z.inputText!==void 0&&(E3($.serverData)||E3({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 X=this.currentTurnId!==Q;if(this.currentTurnId=Q,!X)return;let H=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,...H?{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)){B(`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)=>B(`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(OL*2**Math.min(J-1,4),NL),Q=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=V,B(`codex-process: model capacity retry #${J} in ${Y}ms: ${$}`);let X=setTimeout(()=>{if(this.capacityRetryTimer!==X)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 H=this.beginTurnStart(Z);this.startTurn(Z,H).catch((z)=>this.failTurnStart(z,H))},Y);return this.capacityRetryTimer=X,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){B(`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??{},X={};for(let H of Y.params?.questions??[]){let z=V[H.question]??V[H.id];if(z!==void 0)X[H.id]={answers:[String(z)]}}this.respond($,{answers:X});return}default:p0("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,B(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(B(`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 B(`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 hL($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function p5($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let H=J.exec($);if(!H)break;let z=H[1],G=new RegExp(`^(?: {0,3})${hL(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=H.index+H[0].length;let W=G.exec($),K=W?W.index+W[0].length:$.length;Z.push({start:H.index,end:K}),Y=K}let Q=[...Z],V=[],X=0;for(let H of Z){if(X<H.start)V.push({start:X,end:H.start});X=H.end}if(X<$.length)V.push({start:X,end:$.length});for(let H of V){let z=$.slice(H.start,H.end),G=/(`+)[^\n]*?\1/g,W;while((W=G.exec(z))!==null)Q.push({start:H.start+W.index,end:H.start+W.index+W[0].length})}return Q.sort((H,z)=>H.start-z.start)}function c5($,Z){if(!$)return $;let J=p5($);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 IL($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function RV($){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 o$($){if(Array.isArray($))return $.map((Y)=>o$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=o$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=u5(Z.content);return J}function $0($){return c5($,(Z)=>gL(RV(IL(Z))))}function gL($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
86
+ `:"";this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.capacityRetryEnabled=!0,this.turnError=null;let Q=this.beginTurnStart(J+$);this.startTurn(J+$,Q).catch((Y)=>this.failTurnStart(Y,Q))}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 Q of J.data){if(typeof Q?.model!=="string"||!Q.model)continue;$.push({id:typeof Q.id==="string"&&Q.id?Q.id:Q.model,model:Q.model,displayName:typeof Q.displayName==="string"&&Q.displayName?Q.displayName:Q.model,description:typeof Q.description==="string"?Q.description:"",hidden:Q.hidden===!0,isDefault:Q.isDefault===!0,supportedReasoningEfforts:oL(Q.supportedReasoningEfforts),defaultReasoningEffort:Z$(Q.defaultReasoningEffort)?Q.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 Q=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Q?.data))throw Error("thread/list returned no data array");for(let V of Q.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 X=typeof V.status==="string"?V.status:typeof V.status?.type==="string"?V.status.type:void 0;if(O2("codex",V.id))continue;$.push({provider:"codex",sessionId:V.id,cwd:V.cwd,preview:V.preview,ts:V.updatedAt*1000,...X?{status:X}:{}})}let Y=Q?.nextCursor;if(Y!==null&&typeof Y!=="string")throw Error("thread/list returned an invalid nextCursor");if(Y&&Z.has(Y))throw Error(`thread/list repeated pagination cursor ${Y}`);if(Y)Z.add(Y);J=Y}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){B("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)){B(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(B(`codex-process: turn/start failed: ${J}`),$ instanceof b2&&$.method==="turn/start"&&CV($.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 b2&&$.method==="turn/start"&&Z.inputText!==void 0&&(f3($.serverData)||f3({message:$.serverMessage}))?{codexQuotaFailure:{accepted:!1,rejectedInput:Z.inputText}}:{}})}recordTurnStarted($,Z,J,Q){let Y=typeof $?.id==="string"&&$.id?$.id:null;if(!Y)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Y))return;let V=Q??this.turnStartOwner;if(V?.interrupted){if(this.rememberFinishedTurn(Y),this.turnStartOwner===V)this.turnStartOwner=null;this.interruptTurn(Y);return}this.confirmTurnStart(Y,Q);let X=this.currentTurnId!==Y;if(this.currentTurnId=Y,!X)return;let H=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:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...H?{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 Q=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(Q?.turn,this.sessionId,"turn/start response",J)}catch(Q){if(!this.ownsTurnStartFailure(J)){B(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Q}}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)=>B(`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 Q=Math.min(uL*2**Math.min(J-1,4),lL),Y=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Q,message:$};this.turnRetry=V,B(`codex-process: model capacity retry #${J} in ${Q}ms: ${$}`);let X=setTimeout(()=>{if(this.capacityRetryTimer!==X)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Y!==(this.turnStartGeneration??0))return;if(this.turnRetry={...V,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Y!==(this.turnStartGeneration??0))return;let H=this.beginTurnStart(Z);this.startTurn(Z,H).catch((z)=>this.failTurnStart(z,H))},Q);return this.capacityRetryTimer=X,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Q=this.serverRequests.get(String($));if(!Q){B(`codex-process: permission response for unknown request ${$}`);return}let Y=Z==="allow";switch(Q.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/permissions/requestApproval":if(Y)this.respond($,{permissions:Q.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Y){this.respondError($,J?.denyMessage??"denied by user");return}let V=J?.updatedInput?.answers??{},X={};for(let H of Q.params?.questions??[]){let z=V[H.question]??V[H.id];if(z!==void 0)X[H.id]={answers:[String(z)]}}this.respond($,{answers:X});return}default:i0("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Q.method,params:Q.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,B(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(B(`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("; ")}`:"",Q=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw B(`codex-process: kill failed: ${Q.message}`),Q}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,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!1),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}}});function Yq($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s7($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let H=J.exec($);if(!H)break;let z=H[1],W=new RegExp(`^(?: {0,3})${Yq(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");W.lastIndex=H.index+H[0].length;let G=W.exec($),K=G?G.index+G[0].length:$.length;Z.push({start:H.index,end:K}),Q=K}let Y=[...Z],V=[],X=0;for(let H of Z){if(X<H.start)V.push({start:X,end:H.start});X=H.end}if(X<$.length)V.push({start:X,end:$.length});for(let H of V){let z=$.slice(H.start,H.end),W=/(`+)[^\n]*?\1/g,G;while((G=W.exec(z))!==null)Y.push({start:H.start+G.index,end:H.start+G.index+G[0].length})}return Y.sort((H,z)=>H.start-z.start)}function t7($,Z){if(!$)return $;let J=s7($);if(!J.length)return Z($);let Q="",Y=0;for(let V of J){if(V.start>Y)Q+=Z($.slice(Y,V.start));Q+=$.slice(V.start,V.end),Y=Math.max(Y,V.end)}if(Y<$.length)Q+=Z($.slice(Y));return Q}function Vq($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function IV($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Q,Y)=>{let V=Y.trim();return Q.trim()?`\uD83D\uDDBC️ ${Q.trim()} (${V})`:`\uD83D\uDDBC️ ${V}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function Q1($){if(Array.isArray($))return $.map((Q)=>Q1(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=Q1(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=r7(Z.content);return J}function Z0($){return t7($,(Z)=>Xq(IV(Vq(Z))))}function Xq($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
87
87
  \`\`\`
88
88
  ${J.trim()}
89
89
  \`\`\`
@@ -91,192 +91,193 @@ ${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 u5($){return c5($,RV)}var T;var C0=O(()=>{T={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 D0($,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 TV($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function mL($,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 EV($){return $==="workflow"||$==="monitor"}function G$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function i5($){return $.some((Z)=>!G$(Z))}function d4($,Z,J=Date.now()){let Y=mL(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),X=$.pending.some(Q);if(V||X){let z=(G)=>({...G,...G$(G)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type:Y==="unknown"?G.type:Y,toolUseId:Z.tool_use_id??G.toolUseId,description:Z.description||G.description,subagentType:Z.subagent_type??G.subagentType,workflowName:Z.workflow_name??G.workflowName,prompt:Z.prompt??G.prompt});if(X&&Y==="subagent")return{active:[...$.active,...$.pending.filter(Q).map(z)],pending:$.pending.filter((G)=>!Q(G))};return{active:V?$.active.map((G)=>Q(G)?z(G):G):$.active,pending:X?$.pending.map((G)=>Q(G)?z(G):G):$.pending}}let H={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:[],...EV(Y)?{isBackgrounded:!0}:{}};return Y==="subagent"||EV(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function n5($,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 a5($,Z){let J=$.pending.findIndex((X)=>X.id===Z.task_id),Y=Z.patch;if(Y.is_backgrounded===!0&&J>=0){let X=$.pending[J],H={...X,isBackgrounded:!0,status:Y.status??X.status,description:Y.description??X.description,error:Y.error??X.error,endTime:Y.end_time??X.endTime};return{active:[...$.active,H],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Q=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Q||V){let X=(H)=>({...H,status:Y.status??H.status,description:Y.description??H.description,error:Y.error??H.error,isBackgrounded:Y.is_backgrounded??H.isBackgrounded,endTime:Y.end_time??H.endTime});return{active:Q?$.active.map((H)=>H.id===Z.task_id?X(H):H):$.active,pending:V?$.pending.map((H)=>H.id===Z.task_id?X(H):H):$.pending}}return $}function o5($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function b3($,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 C3($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>pL){J=Y+1;break}return J===0?$:$.slice(J)}function cL($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return U2(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 uL($,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 s5($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>G.toolUseId===Z?{...G,steps:C3([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${cL(Y,Q)}`.trim()}])}:G);return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function t5($,Z,J,Y,Q,V){let X=$.active.some((G)=>G.id===Z),H=$.pending.some((G)=>G.id===Z);if(!X&&!H)return $;let z=(G)=>G.map((W)=>{if(W.id!==Z)return W;if(Q==="started")return{...W,steps:C3([...W.steps,{toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()}])};let K=!1,_=W.steps.map((L)=>{if(K||L.toolUseId!==J)return L;return K=!0,{...L,brief:V?`${L.brief} ${V}`:L.brief}});if(!K&&V)_.push({toolUseId:J,tool:Y,brief:`${Y} ${V}`.trim()});return{...W,steps:C3(_)}});return{active:X?z($.active):$.active,pending:H?z($.pending):$.pending}}function r5($,Z,J,Y,Q){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>{if(G.toolUseId!==Z)return G;let W=!1,K=G.steps.map((_)=>{if(W||_.toolUseId!==J)return _;return W=!0,{..._,brief:`${_.brief} → ${uL(Y,Q)}`}});return{...G,steps:C3(K)}});return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function kV($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of lL)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:`${D0((Y+1)*600,"down")}+`,nextDelayMs:Q-Z}}function T2($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=l5){let Y=Math.floor((J-l5)/xV),Q=l5+(Y+1)*xV;return{label:`${D0((10+Y*5)*60,"down")}+`,nextDelayMs:Q-J}}return{label:D0(Math.floor(J/1000)),nextDelayMs:bV}}return kV($)}function SV($){return $.subagentType??$.workflowName??d5[$.type]}function dL($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function iL($){let Z=[`**${d5[$.type]}**${SV($)!==d5[$.type]?` · ${SV($)}`:""}${G$($)?` · 用时 ${D0(dL($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Z.push(`⚠ ${$.error}`);if($.summary)Z.push("",`**${G$($)?"结果":"进度"}**`,CV($.summary,8000));if($.prompt)Z.push("","**任务说明**",CV($.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 $0(Z.join(`
96
- `))}function CV($,Z){return $.length<=Z?$:`${$.slice(0,Z)}
97
- _这里只显示预览。_`}function k3($){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 e5($){return{tag:"collapsible_panel",element_id:l4.panel($.id),header:{title:{tag:"plain_text",content:k3($)}},expanded:!1,elements:[{tag:"markdown",element_id:l4.body($.id),content:iL($)}]}}var l4,pL=1000,d5,lL,bV=1000,l5=600000,xV=300000;var $6=O(()=>{C0();A3();l4={panel:($)=>`bg_${TV($)}`,body:($)=>`bgb_${TV($)}`};d5={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"},lL=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as nL}from"node:events";import{join as aL,isAbsolute as oL,extname as sL,basename as tL}from"node:path";import{readFile as rL}from"node:fs/promises";function eL($){if($.length>=8&&$.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if($.length>=3&&$[0]===255&&$[1]===216&&$[2]===255)return"image/jpeg";let Z=$.subarray(0,12).toString("ascii");if(Z.startsWith("GIF87a")||Z.startsWith("GIF89a"))return"image/gif";if($.length>=12&&Z.startsWith("RIFF")&&Z.slice(8,12)==="WEBP")return"image/webp";throw Error("DSH image input has unsupported or invalid raster bytes")}var y3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),Z6,J6;var yV=O(()=>{j0();M1();f4();f();Z6={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};J6=class J6 extends nL{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=y3();lastContextWindow=null;lastContextTokens=null;runtime;ready;models=[];busy=!1;closing=!1;startedAt=0;questionInputs=new Map;frames=new Map;toolInputs=new Map;children=new Set;settledChildren=new Set;childText=new Map;earlyNotifications=[];pendingInputs=0;terminalError=null;failedUnexpectedly=!1;constructor($){super();this.opts=$;this.tokenSourceId=$.tokenSourceId,this.lastModel=$.model,this.lastEffort=$.effort;let Z=$.launch??{kind:"fresh"};L0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new F3({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:aL($.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(Z6).find((Y)=>Z6[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)=>!oL(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(sL(V).toLowerCase()))continue;let X=await rL(V);J.push({type:"image",mediaType:eL(X),name:tL(V),data:X.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,X=Z==="allow"?Q.map((H)=>{let z=V?.[H.question];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${H.question}`);let G=H.options?.find((W)=>W.label===z);return{id:H.id,selected:G?[z]:[],...G?{}:{custom:z}}}):void 0;this.runtime.request("question/answer",{id:Y,answers:X,...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:X}),is_error:Z==="deny",parentToolUseId:null})}).catch((H)=>this.fail(H))}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(!_0(Z))throw Error(`invalid DSH effort: ${Z}`);if(await this.initializationPromise(),await this.runtime.request("session/model",{model:$,effort:Z},null),!this.busy)this.lastModel=$,this.lastEffort=Z}async compactThread(){if(await this.initializationPromise(),await this.runtime.request("session/compact",{},null)===null)throw new D1}fail($){let Z=$ instanceof Error?$:Error(String($));if(this.terminalError)return;this.failedUnexpectedly=!this.closing,this.terminalError=Z,this.emit("error",Z);for(let J of this.children){if(this.settledChildren.has(J))continue;this.settledChildren.add(J),this.emit("bg_task_settled",{task_id:J,status:"failed",summary:Z.message})}if(this.busy||this.pendingInputs>0)this.busy=!1,this.lastResult={...y3(),is_error:!0,subtype:"error"},this.emit("result",{errors:[Z.message],error:Z.message,...this.lastResult});this.kill().catch((J)=>this.emit("error",J))}onNotification({method:$,params:Z}){let J=Z.sessionId!==this.sessionId;switch($){case"failure":this.fail(Error(Z.message));return;case"agent.error":this.emit("error",Error(Z.message));return;case"subagent.started":this.children.add(Z.sessionId),this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});return;case"subagent.disposed":if(this.children.has(Z.sessionId)&&!this.settledChildren.has(Z.sessionId))this.emit("bg_task_settled",{task_id:Z.sessionId,status:"stopped",summary:this.childText.get(Z.sessionId)??""});this.children.delete(Z.sessionId),this.settledChildren.delete(Z.sessionId),this.childText.delete(Z.sessionId);for(let Y of this.frames.keys())if(Y.startsWith(`${Z.sessionId}:`))this.frames.delete(Y);return;case"session.status":return;case"question":{this.questionInputs.set(Z.id,Z.questions);let Y={questions:Z.questions.map((Q)=>({...Q,question:Q.detail?`${Q.question}
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 X=Y.chunk;if(X.type==="text-delta"){if(J)this.childText.set(Z.sessionId,(this.childText.get(Z.sessionId)??"")+X.text);this.emit("assistant_text",{text:X.text,parentToolUseId:J?Z.sessionId:null})}else if(X.type==="block-end"&&X.block.type==="text"&&!J)this.emit("assistant_block_stop",{parentToolUseId:null});else if(X.type==="usage"&&!J)this.observeUsage(X.usage);return}case"session.event":{let Y=Z.event,Q=Y.data;if(!Y||!Q||typeof Y.type!=="string")throw Error("invalid DSH session event");if(Y.type==="turn/start"&&!J)this.busy=!0,this.startedAt=Date.now(),this.lastUsage=null,this.lastResult=y3(),this.emit("scheduled_turn_input",{text:"DeepSeek Harness 继续执行",promptId:`dsh-turn-${Q.turn}`}),this.emit("turn_started",{turn_id:String(Q.turn),thread_id:this.sessionId});else if(Y.type==="turn/start"&&J&&this.settledChildren.delete(Z.sessionId))this.emit("bg_task_started",{task_id:Z.sessionId,description:"DeepSeek Harness 子 Agent",task_type:"agent",tool_use_id:Z.sessionId});else if(Y.type==="request/header"&&!J&&Q.header?.config)this.lastModel=Q.header.config.model,this.lastEffort=Q.header.config.reasoningEffort,this.lastContextWindow=this.models.find((V)=>V.model===this.lastModel)?.contextWindow??null;else if(Y.type==="tool/call"){let V=JSON.parse(Q.arguments),X=Z6[Q.name]??Q.name;if(["read","write","edit"].includes(Q.name)&&V.path)V.file_path=V.path;this.toolInputs.set(Q.callId,{name:X,input:V}),this.emit("tool_use",{id:Q.callId,name:X,input:V,parentToolUseId:J?Z.sessionId:null})}else if(Y.type==="tool/result"){let V=Q.message?.content?.[0];if(V?.type!=="tool-result"||typeof V.toolCallId!=="string")throw Error("invalid DSH tool result");this.emit("tool_result",{tool_use_id:V.toolCallId,content:V.content,is_error:V.isError===!0,parentToolUseId:J?Z.sessionId:null}),this.toolInputs.delete(V.toolCallId)}else if(Y.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Q.todos.map((V)=>({step:V.content,status:V.status==="in_progress"?"inProgress":V.status}))});else if(Y.type==="compaction/start"&&!J)this.emit("context_compacted",{threadId:this.sessionId,phase:"start",sourceType:"dsh"});else if(Y.type==="compaction/end"&&!J)if(Q.error)this.emit("error",Error(`DSH compaction: ${Q.error}`));else this.emit("context_compacted",{threadId:this.sessionId,phase:"end",sourceType:"dsh"});else if(Y.type==="goal/change"&&!J)if(Q.operation==="clear")this.emit("thread_goal_cleared",{threadId:this.sessionId});else this.emit("thread_goal_updated",{threadId:this.sessionId,objective:Q.goal.objective,status:Q.goal.phase,tokenBudget:null,tokensUsed:Number.NaN,timeUsedSeconds:Number.NaN});else if(Y.type==="turn/end"&&J&&this.children.has(Z.sessionId))this.settledChildren.add(Z.sessionId),this.emit("bg_task_settled",{task_id:Z.sessionId,status:Q.reason.kind==="completed"?"completed":Q.reason.kind==="aborted"?"stopped":"failed",summary:this.childText.get(Z.sessionId)??""}),this.childText.delete(Z.sessionId);return}case"settled":{if(J)throw Error("DSH settled a different root session");this.busy=!1;let Y=Z.event,Q=Y.data.reason;this.lastCompletedTurnId=String(Y.seq),this.lastResult={...y3(),duration_ms:Date.now()-this.startedAt,num_turns:1,usage:this.lastUsage,subtype:Q.kind,is_error:Q.kind!=="completed"},this.emit("result",{...this.lastResult,...Q.kind!=="completed"?{error:Q.error?.message??`DSH turn ended: ${Q.kind}`,errors:[Q.error?.message??`DSH turn ended: ${Q.kind}`]}:{},checkpoint:{provider:"dsh",kind:"event",id:String(Y.seq),source:{provider:"dsh",sessionId:this.sessionId,cwd:this.opts.workDir}}});return}default:B(`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 s$($){return $.startsWith("claude:")?$:`claude:${$}`}function i4($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(v.claude.models,Z))return v.claude.models[Z]?.model?.trim()||"opus";return Z}var Y6=O(()=>{S0()});import{existsSync as $P,readFileSync as ZP}from"node:fs";function Q6(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:JQ}function a4(){if(n4!==null)return n4;try{n4=$P(Q6())?JSON.parse(ZP(Q6(),"utf8")):{}}catch($){B(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),n4={}}return n4??{}}function YP(){try{o(Q6(),a4())}catch($){B(`context-window-observe: cache write MISS (${$?.message??$})`)}}function V6($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function wV($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=V6($,Z),Q=a4()[Y];if(Q===J)return;a4()[Y]=J,YP(),B(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function w3($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=a4()[V6($,Z)];return J!=null&&J<JP?Z:`${Z}[1m]`}function E2($,Z){return a4()[V6($,Z)]}var JP=1e6,n4=null;var o4=O(()=>{Q0();f();x0()});var K6={};S$(K6,{toolsFromProfile:()=>aV,settingSourcesFromProfile:()=>nV,resolveClaudeExecutableConfig:()=>W6,resetClaudeContextWindowCache:()=>GP,readProjectMcpServers:()=>oV,readLastCallUsageFromTranscript:()=>lV,claudeTranscriptPath:()=>I3,claudeTranscriptDir:()=>h3,claudeManagedSkillOptions:()=>cV,buildClaudeSpawnPath:()=>uV,assertClaudeCodeAvailable:()=>G6,ClaudeAgentProcess:()=>g3,CLAUDE_PERMISSION_MODE:()=>iV});import{existsSync as gV,readFileSync as mV}from"node:fs";import{homedir as f3}from"node:os";import{spawn as QP}from"cross-spawn";import{delimiter as vV,join as A1}from"node:path";import{EventEmitter as VP}from"node:events";function cV($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function XP($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function HP($){let Z=QP($.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 G6(){W6(),G5("claude","@anthropic-ai/claude-agent-sdk")}function W6($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?v.claude.bin:$.configuredBin;if(J){if(!($.exists??gV)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&XP(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:HP,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function uV(){if(process.platform==="win32")return process.env.PATH??"";let $=[A1(f3(),".local","npm-global","bin"),A1(f3(),".local","bin"),A1(f3(),".bun","bin"),...(process.env.PATH??"").split(vV),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(vV)}function zP($){let Z=M2($);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 fV($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function h3($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||A1(f3(),".claude");return A1(J,"projects",Z)}function I3($,Z){return A1(h3($),`${Z}.jsonl`)}function lV($){let Z;try{Z=mV($,"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 X=V.message.usage;if((X.input_tokens??0)+(X.cache_read_input_tokens??0)+(X.cache_creation_input_tokens??0)+(X.output_tokens??0)>0)return X}}catch{}}return null}function hV($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function GP(){H6.clear()}function WP($){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)+x2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+x2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+x2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+x2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+x2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=x2(V.contextWindow??V.context_window);if(X>0)J=Math.max(J??0,X)}let Y=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Y<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Y,{usage:Z,contextWindow:J}}function v3($){return{...$}}function X6($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function KP($,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 x2($){return typeof $==="number"&&Number.isFinite($)?$:0}function dV($){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 BP($){let Z=dV($);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 _P($){return`server_tool:${$}`}function jP($){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 LP($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function PP($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[i$];return{id:s$($.value),model:s$($.value),displayName:$.displayName||s$($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(i$)?i$:Z[0]}}function nV($){if(!$?.settingSources)return[...IV];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...IV]}function aV($){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 oV($){let Z=A1($,".mcp.json"),J;try{J=mV(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")B(`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;B(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){B(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function qP($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>FP(Y)).filter((Y)=>Y!==null)}function FP($){let Z=$&&typeof $==="object"?$:{question:$},J=z6(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=DP(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 DP($){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=z6(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let V=z6(Y.description,Y.detail,Y.preview);Z.push(V?{label:Q,description:V}:{label:Q})}return Z}function z6(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var pV,H6,iV="default",IV,g3;var S2=O(()=>{L2();S0();f();j0();Y6();o4();pV=class pV{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($))}};H6=new Map;IV=["project","local"];g3=class g3 extends VP{provider="claude";tokenSourceId;opts;input=new pV;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?s$($.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 $=i4(this.opts.model),Z=this.opts.profile;if(Z)B(`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??nV(Z),Y=cV(J,this.opts.managedSkillPluginPath),Q=aV(Z),V=Z?.strictMcp===!0,X=Z?.loadProjectMcp!==!1?oV(this.opts.workDir):void 0;try{let H=W6(),{query:z}=await SQ();if(!this.alive||this.abortController.signal.aborted)return;let G={...process.env,PATH:uV(),...v.claude.env,...this.opts.hostEnv??{}},W=this.opts.transformEnv?this.opts.transformEnv(G):G;if(W.CLAUDE_CODE_ENABLE_TODO_TOOLS="1",this.opts.effort==="default")W.CLAUDE_CODE_EFFORT_LEVEL="unset";B(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${H.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}:{},...H.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:H.pathToClaudeCodeExecutable}:{},...H.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:H.spawnClaudeCodeProcess}:{},permissionMode:iV,env:W,settingSources:[...J],...this.opts.settings?{settings:this.opts.settings}:{},...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...V?{strictMcpConfig:!0}:{},...X?{mcpServers:X}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(K,_,L)=>this.canUseTool(K,_,L),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(K)=>{let _=K.trim();if(_)B(`claude-agent-process[stderr]: ${_}`)}}})}catch(H){let z=H instanceof Error?H:Error(String(H));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(H){this.initializationError=H instanceof Error?H:Error(String(H)),this.emit("error",this.initializationError),await this.kill()}}sendUserText($,Z=[]){if(!this.alive){B("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));B(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>B(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){B(`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={}){B("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 B(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw B(`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(PP)}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=i4($);if(!F0(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)");try{await this.query.setModel(J)}catch(Y){throw this.lastModel=null,this.lastEffort=null,new D2(`模型设置未确认:${Y instanceof Error?Y.message:String(Y)}`,null,{cause:Y})}this.opts.model=$,this.lastModel=J?s$($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Y){throw new D2(`模型已切换为 ${$},但思考档位未确认:${Y instanceof Error?Y.message:String(Y)}`,$,{cause:Y})}this.opts.effort=Z,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",X),this.off("error",H)},Q=()=>{if(J)return;J=!0,Y(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new D1)},X=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},H=(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",X),this.once("error",H)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=qP(Z);if(Y.length===0)return B("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},V=`claude_perm_${++this.requestCounter}`,X=J.toolUseID||V,H={request_id:V,tool_name:"AskUserQuestion",input:Q,tool_use_id:X},z=new Promise((G)=>{let W=(_)=>{J.signal.removeEventListener("abort",K),G(_)},K=()=>{if(!this.pendingPermissions.delete(V))return;W({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:W,request:H})});return this.emitToolUseOnce(X,"AskUserQuestion",Q,null),this.emit("can_use_tool",H),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){B(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}B(`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(),B(`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:B(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=s$($.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":B(`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){B("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":B(`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){B("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){B(`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:B(`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=s$(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=jP(Q.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(LP(Q.text))continue;let X=$.uuid??Z?.id;this.emit("assistant_text",{uuid:X,text:Q.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:X,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,_P(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,BP(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())B(`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=dV(Y.content),X=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
106
- `):"",H=V||X;this.emitToolResultOnce(Y.tool_use_id,H,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=zP($.usage),J=$.modelUsage??$.model_usage,Y=WP(J);if(!Z&&!Y.usage)B(`claude-agent-process: result usage missing rootKeys=${X6($).join(",")||"-"} usageKeys=${X6($.usage).join(",")||"-"} modelUsageKeys=${X6(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=v3(Y.usage),this.lastTotalUsage=v3(Y.usage);else if(Z)this.cumulativeUsageFromResults=KP(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=v3(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?v3(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let H=hV(this.opts.model,this.tokenSourceId);if(H6.set(H,Y.contextWindow),this.tokenSourceId)for(let[z,G]of Object.entries(J??{})){let W=G?.contextWindow;if(typeof W==="number"&&W>0)wV(this.tokenSourceId,z,W)}}this.lastContextWindow=H6.get(hV(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=I3(this.opts.workDir,this.sessionId??""),V=lV(Q);if(this.lastContextTokens=fV(V)??(gV(Q)?fV(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 X=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:X,is_error:$.is_error===!0||X!=="success"},this.emit("result",{subtype:X,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??X)}:{},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 rV={};S$(rV,{waitForTokenSourceModelRefresh:()=>N1,tokenSourceRuntimeModels:()=>b2,tokenSourceRuntimeModel:()=>U$,tokenSourceRegistryRevision:()=>_6,tokenSourceProcessRevision:()=>k2,tokenSourceFactories:()=>O1,setDefaultTokenSource:()=>P6,scrubDshEnv:()=>s4,scrubAnthropicEnv:()=>r0,resetTokenSourceRegistry:()=>q6,registerTokenSourceFactory:()=>M0,registerTokenSource:()=>j6,refreshAllTokenSourceModels:()=>r4,pendingTokenSourceModelRefresh:()=>y2,listTokenSourcesByAgent:()=>tV,listTokenSources:()=>$$,listEnabledTokenSourcesByAgent:()=>L6,getTokenSourceForAccount:()=>V0,getTokenSource:()=>e0,ANTHROPIC_ENV_KEYS:()=>p3});function r0($){let Z={...$};for(let J of p3)delete Z[J];return Z}function s4($){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 b2($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function U$($,Z){let J=(Y)=>$.agent==="claude"?Y?.replace(/\[1m\]$/,""):Y;return b2($).find((Y)=>J(Y.model)===J(Z))}function k2($,Z){let J=$?.spawnRevision??null,Y=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Y===void 0?J:JSON.stringify([J,Y])}function M0($){sV.set($.kind,$)}function O1(){return[...sV.values()]}function _6(){return B6}function j6($,Z){if(t4.set($.id,$),Z?.default||m3===null)m3=$.id}function e0($){return $?t4.get($):void 0}function V0($,Z="default"){let J=e0($);return J?.forAccount?J.forAccount(Z):J}function $$(){return[...t4.values()]}function tV($){return $$().filter((Z)=>Z.agent===$)}function L6($){return tV($).filter((Z)=>Z.enabled)}function P6($){if(t4.has($))m3=$}function q6(){t4.clear(),m3=null,B6++}function r4(){let $=B6;if(C2?.generation===$)return C2.promise;let Z=Promise.allSettled($$().map(async(J)=>{await J.refreshModels(),B(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(C2?.promise===Z)C2=null});return C2={generation:$,promise:Z},Z}function y2(){return C2?.promise??null}async function N1(){let $;while($=y2())await $}var p3,sV,t4,m3=null,B6=0,C2=null;var Z0=O(()=>{f();p3=["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"];sV=new Map;t4=new Map});import{createHash as MP}from"node:crypto";class W${now;entries=new Map;constructor($=()=>Date.now()){this.now=$}read($,Z){let J=this.entries.get($);if(J?.pending)return J.pending;if(J&&this.now()<J.retryAt)return J.failed?Promise.reject(J.error):Promise.resolve(J.value);J??={failed:!1,failures:0,retryAt:0},this.entries.set($,J);let Y=J,Q=(X,H=0)=>{Y.failures=X?0:Y.failures+1;let z=X?t$:Math.min(UP,t$*2**Math.min(Y.failures-1,3));Y.retryAt=this.now()+Math.max(z,Number.isFinite(H)?H:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Y)Y.value=X,Y.failed=!1,Y.error=void 0,Q(X.state==="ok"||X.state==="not_applicable",X.retryAfterMs);return X},(X)=>{if(this.entries.get($)===Y)Y.value=void 0,Y.failed=!0,Y.error=X,Q(!1);throw X}).finally(()=>{if(Y.pending===V)Y.pending=void 0});return Y.pending=V,V}prime($,Z){this.entries.set($,{value:Z,failed:!1,failures:0,retryAt:this.now()+t$})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function w2($,Z,J){return MP("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function R1($,Z=Date.now()){let J=$.get("retry-after");if(!J)return;let Y=Number(J),Q=Number.isFinite(Y)?Y*1000:Date.parse(J)-Z;return Number.isFinite(Q)&&Q>=0?Q:void 0}function v2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var t$=60000,UP=300000;var T1=()=>{};import{spawn as AP}from"cross-spawn";import{EventEmitter as OP}from"node:events";import{StringDecoder as NP}from"node:string_decoder";import{createHash as RP}from"node:crypto";function D6($,Z){if(l3.set($,Z),Z.state==="ok")e4.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")e4.delete($)}function $X($,Z,J=(Y)=>new r$({accountId:Y})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Y=c3.get($);if(Y)return Y.key===Z?Y.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Q=Promise.resolve().then(async()=>{let V=J($),X,H;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");f2($);let G;try{G=await E1(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{f2($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(G?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(G)};请用 codex-accounts 核对后再操作`);let W=Z$.get($),K;try{K=await d3.read($,async()=>M6(await A6(()=>V.request("account/rateLimits/read",{})),z.planType))}catch(_){K={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(Z$.get($)!==W)K={state:"auth_failed"};else D6($,K);if(K.state!=="ok")B(`codex-reset: ${$} quota refresh failed: ${K.state==="network"?K.reason:K.state}`);X={outcome:G.outcome,usage:K}}catch(z){H=z,B(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let G=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(B(`codex-reset: ${$}: ${G}`),X)X.cleanupError=G;else throw AggregateError([H,z],`${String(H)};${G}`)}if(!X)throw H;return X}).finally(()=>{if(c3.get($)?.promise===Q)c3.delete($)});return c3.set($,{key:Z,promise:Q}),Q}function ZX($,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 TP($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function u3($){if(!$)return null;return{percent:TP($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function EP($){let Z=u3($?.primary),J=u3($?.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 xP($){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:X,weekly:H}=EP(V);if(!X&&!H)continue;Y.push({limitId:Q,limitName:V?.limitName??null,fiveHour:X,weekly:H,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function SP($){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 JX($,Z=m){let J=SP($),Y=l3.get(Z),Q=Y?.state==="ok"?Y.buckets??[]:[],V=Q.filter((X)=>eV(X.fiveHour,u3($?.primary))&&eV(X.weekly,u3($?.secondary)));if(Q.length>0&&V.length===0)B(`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)B(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${V[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function eV($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function CP($){let Z=new r$({accountId:$});try{await Z.initialize("lodestar-usage");let Y=(await ZX(Z.request("account/read",{}),F6))?.account;if(!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let Q=await A6(()=>Z.request("account/rateLimits/read",{}));return M6(Q,Y.planType)}catch(J){if(B(`usage: codex app-server usage failed: ${J?.message??J}`),n3(J))return{state:"auth_failed"};if(v2(J))return{state:"rate_limited"};return{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function M6($,Z){let{buckets:J,defaultLimitId:Y}=xP($),Q=J.find((X)=>X.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};let V=Z??$?.rateLimits?.planType??void 0;return Q.fiveHour=w5(V,Q.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:RP("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 YX($=m){return e4.get($)??null}function QX($=m){let Z=YX($);return Z&&Date.now()>=Z.fetchedAt&&Date.now()-Z.fetchedAt<t$?Z:null}function U6($=m){let Z=Z$.get($)??0;return{accountId:$,read:()=>(Z$.get($)??0)===Z?YX($):null}}function h2($=m){let Z=Z$.get($)??0;return d3.read($,async()=>{try{return await CP($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(n3(J))return{state:"auth_failed"};if(v2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((Z$.get($)??0)!==Z)return{state:"auth_failed"};return D6($,J),J})}function i3($,Z=m){let J=Z$.get(Z)??0;return d3.read(Z,async()=>{try{let Y=M6(await A6(()=>$("account/rateLimits/read",{})));if(Y.state!=="ok")B(`usage: refresh from connection: ${Y.state==="network"?Y.reason:Y.state}`);return Y}catch(Y){throw B(`usage: refresh from connection failed: ${Y instanceof Error?Y.message:String(Y)}`),Y}}).then((Y)=>{if((Z$.get(Z)??0)!==J)return null;if((Z$.get(Z)??0)===J)D6(Z,Y);return Y}).catch((Y)=>{if((Z$.get(Z)??0)===J){if(l3.delete(Z),n3(Y))e4.delete(Z)}return null})}function XX(){return VX}function f2($){VX++,Z$.set($,(Z$.get($)??0)+1),l3.delete($),e4.delete($),d3.invalidate($)}function n3($){let Z=$ instanceof Error?$.message:String($);return/\b(?:401|403)\b|unauthori[sz]ed|not authenticated|authentication (?:failed|required)|not logged in/i.test(Z)}function A6($){return E1($,"额度查询",{retryRateLimits:!1})}async function E1($,Z="额度查询",J={}){let Y=[1000,4000];for(let Q=0;;Q++)try{return await ZX($(),F6)}catch(V){let X=V instanceof Error?V.message:String(V);if(n3(V))throw V;if(J.retryRateLimits===!1&&v2(V))throw V;if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(X))throw V;if(Q>=Y.length)throw Error(`Codex ${Z}失败(已尝试 ${Q+1} 次):${X}`,{cause:V});B(`usage: ${Z} retry ${Q+1}/${Y.length} in ${Y[Q]}ms: ${X}`),await new Promise((z)=>setTimeout(z,Y[Q]))}}var F6=1e4,l3,e4,d3,c3,r$,Z$,VX=0;var A$=O(()=>{U1();f();S0();w0();T1();l3=new Map,e4=new Map,d3=new W$;c3=new Map;r$=class r$ extends OP{proc;buf="";decoder=new NP("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??m;this.proc=AP($.bin??c4(),["app-server","--listen","stdio://",...$.args??k.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??k.env(Z,{...process.env,...v.codex.env},!0,$.login)}),this.exitPromise=new Promise((Y)=>{this.resolveExit=Y}),this.proc.stdout.on("data",(Y)=>this.onStdout(Y)),this.proc.stderr.on("data",(Y)=>{let Q=Y.toString().trim();if(Q)B(`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)=>{B(`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}`))}),n$(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
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 B(`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}`}})+`
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"})+`
110
- `,(Y)=>Y?J(Y):Z())})}isAlive(){return this.alive}request($,Z,J=F6){let Y=this.nextId++;return new Promise((Q,V)=>{if(!this.alive){V(Error(`codex app-server is not alive; cannot request ${$}`));return}let X=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:X});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
111
- `,(H)=>{if(!H)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 ${$}: ${H.message}`))})}catch(H){this.pending.delete(Y),clearTimeout(X),V(H instanceof Error?H:Error(String(H)))}})}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)}}};Z$=new Map});import{existsSync as bP,readFileSync as kP}from"node:fs";class HX{deps;constructor($){this.deps=$}blocks(){if(!bP(this.deps.stateFile))return[];let $=JSON.parse(kP(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"?p4($.usage,Z):null,Y=["fiveHour","weekly"].flatMap((H)=>{let z=J?.[H];return z?[{kind:H,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Q=v5($.usage,Z),V=JSON.stringify([$.identity,Q]),X=this.blocks().filter((H)=>H.key!==V);X.push({key:V,identity:$.identity,meter:Q,windows:Y}),o(this.deps.stateFile,{version:1,blocks:X})}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(j)=>{let q,F=null,R=`record:${j.id}`;if(this.deps.pendingLogin(j.id))q={state:"network",reason:"正在登录"};else try{q=J?this.deps.cachedUsage(j.id):await this.deps.usage(j.id);let D=q?.state==="ok"?q.accountFingerprint??this.deps.identity(j.id):null;if(D)R=D;else if(q?.state==="ok")F="账号身份 MISS";if(q?.state==="ok"&&!F)F=await this.deps.compatible(j.id,Z.model,Z.effort)}catch(D){q={state:"network",reason:String(D)}}return{account:j,usage:q,identity:R,reason:F}}));Z.signal?.throwIfAborted();let Q=Z.failedAccountId&&Y.find((j)=>j.account.id===Z.failedAccountId);if(Q&&Q.usage?.state==="ok")this.block({account:Q.account,usage:Q.usage,identity:Q.identity,...f5(Q.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let V=this.blocks(),X=this.deps.now(),H=new Set,z=new Map,G=Y.map(({account:j,usage:q,identity:F,reason:R})=>{let D=f5(q??{state:"network",reason:"尚无额度缓存"},Z.model,X,Z.effort);if(R)D={...D,state:"miss",score:null,reason:R};let U=z.get(F);if(z.set(F,U??j.name),U)D={...D,state:"miss",score:null,reason:`重复账号:${U}`};let A=q?.state==="ok"?v5(q,Z.model):null,x=V.find((S)=>(S.identity===F||S.identity===`record:${j.id}`)&&S.meter===A);if(x&&q?.state==="ok"&&D.state==="ready"){let S=p4(q,Z.model);if(!J&&x.windows.some((y)=>{let g=S[y.kind];return g&&g.percent!==null&&(y.percent!==null&&g.percent<y.percent||y.reset!==null&&y.reset<=X&&(g.resetsAt?.getTime()??0)>y.reset)}))H.add(x.key);else D={...D,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:j,usage:q,identity:F,...D,...U?{duplicateOf:U}:{}}});if(H.size)o(this.deps.stateFile,{version:1,blocks:V.filter((j)=>!H.has(j.key))});let W=G.filter((j)=>j.state==="ready");W.sort((j,q)=>q.score-j.score||(q.availableNow??0)-(j.availableNow??0)||j.account.id.localeCompare(q.account.id));let K=W[0]??null,_=G.filter((j)=>j.state==="exhausted"||j.state==="waiting"),L=_.length?Math.min(..._.map((j)=>j.retryAt??X+60000)):void 0;for(let j of G)B(`codex scheduler${J?" [cache]":""}: ${j.account.name} ${j.state} score=${j.score??"MISS"}${j.reason?` (${j.reason})`:""}`);return{selected:K,candidates:G,...L!==void 0?{retryAt:L}:{}}}}var a3;var O6=O(()=>{w0();A$();Z0();Q0();x0();f();a3=new HX({accounts:()=>k.list(),usage:h2,cachedUsage:QX,identity:($)=>k.fingerprint($),pendingLogin:O2,now:Date.now,stateFile:ZQ,compatible:async($,Z,J)=>{let Y=V0("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=U$(Y,Z);return!Q||Q.unavailableReason||J&&!Q.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as yP}from"node:events";function fP($,Z){return Z.throwIfAborted(),new Promise((J,Y)=>{let Q=()=>{clearTimeout(X),Z.removeEventListener("abort",V)},V=()=>{Q(),Y(Z.reason)},X=setTimeout(()=>{Q(),J()},$);Z.addEventListener("abort",V,{once:!0})})}var wP="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",vP,N6=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),R6;var zX=O(()=>{w0();O6();A$();f();vP=["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"];R6=class R6 extends yP{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??N6()}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??a3}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},B(`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((H)=>`${H.account.name}:${H.reason??H.state}`).join(";");if(Y.retryAt===void 0){let z=Y.candidates.some((G)=>G.state==="miss"&&!G.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())),X=Y.candidates.filter((H)=>H.state==="miss"&&!H.duplicateOf).length;B(`codex account: waiting for quota: ${Q}`),this.notice(`暂无可用账号 · 自动等待恢复${X?` · ${X} 个 MISS`:""}`,V),this.resolveQuotaWait(),await(this.opts.wait??fP)(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:X}=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=X,n$(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 H=V.initializationPromise?.();if(!H)throw Error("Codex 初始化未提供确认事务");if(await H,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 vP)$.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 H=await i3(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),H?.state==="ok")this.selected={...this.selected,usage:H,identity:H.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 H of this.backgroundTasks)this.emit("bg_task_settled",{task_id:H,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 X=Z.accepted?wP:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(X),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...N6(),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={...N6(),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 $9($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new R6({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,_,L,j,q)=>$9({...$,model:j,effort:q,codexAccountPreference:void 0,codexManualAccount:L,codexAccountId:K,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??m,J=V0($.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=k2(J,Q),X=!Y&&J&&U$(J,Q);if(!Y&&J&&Q&&!X)throw Error(`model is not present in token source ${J.id}: ${Q}`);if(!Y&&X&&(X.unavailableReason||!X.efforts.length||$.effort!==void 0&&!X.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Q}/${$.effort??"MISS"}`);let H=!Y&&J&&Q?J.resolveSpawnModel(Q):Q;if(Q&&!H)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Q}`);let z=J?(W)=>J.spawnEnv(W,H):void 0;if($.provider==="dsh"){if(!J||!H||!_0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new J6({...$,model:H,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(G6(),!F0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new g3({workDir:$.workDir,model:H,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&&!t0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let G=new R2({workDir:$.workDir,model:H,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z});return n$(G,Z),{process:G,sourceRevision:V}}var T6=O(()=>{j0();yV();S2();U1();Z0();w0();zX()});function o3($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function GX($){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 x1($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function E6($){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 IP($){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 gP($){let Z=x1($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${E6($.file.url)})`:Z,Y=$.status==="failed"?`<font color='red'>${x1($.error??"交付失败")}</font>`:`<font color='grey'>${GX($.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:IP($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
112
- ${Y}`}]}]}}function x6($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Y=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Q=$.folderAccessReady&&$.folder?E6($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],X=V.slice(0,hP),H=V.slice(X.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:T.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(gP),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${H?`中有 ${H} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${x1($.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 S6($){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
- 工作目录:${x1($.workDir)}
114
- 群:${x1($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:x1($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${x1($.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?.enabled&&!$.settings.folder?[{tag:"markdown",content:"本群首次交付时创建独立云空间文件夹。"}]:[],...$.settings?.folder?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:E6($.settings.folder.url)}]}]:[]]}}}var hP=12;var s3=O(()=>{C0()});function t3($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function r3($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function mP($,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 KX($,Z,J){let Y=mP($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function WX($){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 e3($,Z){let J=WX($);return Z!=null&&Z>0?`${J}/${WX(Z)}`:`${J}/--`}function BX($,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 b6($,Z,J){let Y=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Y||"MISS"}/${J||"MISS"}`}function Z8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function pP($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function cP($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function $8($){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 _X($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function LX($){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 uP($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${LX($)}`}function C6($){return typeof $==="number"&&Number.isFinite($)?$:null}function lP($){let Z=C6($.startedAtMs),J=C6($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${D0((J-Z)/1000)}`}function dP($){let Z=C6($);return Z==null?null:$8(Z)}function iP($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=dP($.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 k6($,Z,J){if($==null||!Number.isFinite($))return null;let Y=KX($,Z,J);return Y?`${Y.used}% · ${e3($,Z)}`:"--"}function y6($){let Z=$8($?.input_tokens??Number.NaN),J=$8($?.cache_read_input_tokens??Number.NaN),Y=$8($?.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?"✅":"⏳",X=Q?lP(Y):"",H=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,z=iP(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
115
- `)}]}}function PX($,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(`- ${pP(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(`
116
- `)}function w6($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:uP($,J)}},expanded:!1,elements:[{tag:"markdown",content:PX($,Z,J)}]}}function J9($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${LX($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:PX($,Z)}]}}function v6($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${_X($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${D0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${_X($.status)}: ${cP($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
117
- `)}]}}function J8($){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:T.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((X)=>({tag:"markdown",content:$0(X)}))}]:[];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:T.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function qX($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function nP($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function aP($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let V=$.options[Q],X=V.description?` · ${$0(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:`**${$0(V.label)}**${X}`}]})}return Y}function jX($,Z,J,Y){if($.length===0)return null;let Q=$.length,V=[];for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let z=qX(H,X,Q),G=Y.get(X);if(G){let W=nP(H,G),K=[`**✅ ${z}**`,`**回答**:${W}`];V.push({tag:"markdown",content:K.join(`
118
- `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),H.options.length>0)V.push(...aP(H,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function I2($,Z,J,Y="\uD83E\uDD14",Q){let V=J.length,X=Q?.answered??new Map,H=Q?.currentIdx,z=H===void 0&&X.size>0,G=[],W;if(Q?.waitingFor)W=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",G.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){W=`${Y} 已回答 · ${V}/${V}`,G.push(...jX(J,Z,H,X)??[]);let K=[...X.values()].reverse().find((_)=>_.user)?.user;if(K)G.push({tag:"markdown",content:`
119
- *— 由 ${K} 回答*`})}else if(H!==void 0&&J[H])W=`${Y} 等你确认 · ${H+1}/${V}`,G.push(...jX(J,Z,H,X)??[]);else if(W=`${Y} 等你确认`,J[0])G.push({tag:"markdown",content:`**${qX(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!z&&!Q?.waitingFor,elements:G}}var FX=O(()=>{C0()});import{isAbsolute as f6,relative as oP}from"node:path";function Q8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function V8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function tP($){return Q8($)||V8($)}function X8($){return $==="FileChange"||$==="fileChange"}function Q9($){return $==="WebSearch"||$==="webSearch"}function H8($){return $==="WebFetch"||$==="webFetch"}function c6($){return $==="MCP"}function V9($){return $==="ImageGeneration"||$==="imageGeneration"}function u6($){return $==="Agent"||$==="Task"}function z8($){return $==="Read"}function G8($){return $==="Write"}function W8($){return $==="Edit"||$==="NotebookEdit"}function K8($){return $==="MultiEdit"}function l6($){return $==="Glob"||$==="Grep"||$==="LS"}function B8($){return $==="TodoWrite"}function _8($){return $==="ExitPlanMode"}function j8($){return $.startsWith(MX)}function UX($){return j8($)?$.slice(MX.length):$}function S1($){if(j8($))return"服务端工具";if(X8($))return"文件变更";if(Q9($))return"网页搜索";if(H8($))return"网页读取";if(V9($))return"图片生成";if(z8($))return"读取文件";if(G8($))return"写入文件";if(W8($)||K8($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(B8($))return"更新待办";if(_8($))return"确认计划";if($==="Task")return"子任务";return tP($)?"Bash":$}function e$($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(j8($))return J(rP($,Z),80);if(!Z||typeof Z!=="object")return"";if(Q8($))return eP(Z);if(V8($))return $q(Z);if(X8($))return J(Yq(Z),80);if(Q9($))return J(IX(Z),80);if(H8($))return J(Wq(Z),80);if(c6($))return J(Bq(Z),80);if(V9($))return J(jq(Z),80);if(u6($))return J(Lq(Z),80);if(z8($))return J(Qq(Z),80);if(G8($))return J(Vq(Z),80);if(W8($))return J(Xq(Z),80);if(K8($))return J(Hq(Z),80);if(l6($))return J(zq($,Z),80);if(B8($))return J(Gq(Z),80);if(_8($))return J(X9(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 rP($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:UX($),Y=X9(Z?.input);return Y?`${J}: ${Y}`:J}function eP($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=OX($);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(U2(Y),46)}`}function AX($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function $q($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${AX($)}${J}`}function OX($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=k5(Z);return{description:Y.description||J,command:Y.command}}function c0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
94
+ `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function r7($){return t7($,IV)}var E;var C0=O(()=>{E={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 U0($,Z="nearest"){if(!Number.isFinite($)||$<0)return"MISS";let[J,Q]=$>=3600?[$/3600,"h"]:$>=60?[$/60,"m"]:[$,"s"];return`${Z==="down"?Math.floor(J*10)/10:Number(J.toFixed(1))}${Q}`}function gV($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function Hq($,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 mV($){return $==="workflow"||$==="monitor"}function B$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function Z6($){return $.some((Z)=>!B$(Z))}function r4($,Z,J=Date.now()){let Q=Hq(Z.task_type,Z.subagent_type),Y=(z)=>z.id===Z.task_id||!!Z.tool_use_id&&z.toolUseId===Z.tool_use_id,V=$.active.some(Y),X=$.pending.some(Y);if(V||X){let z=(W)=>({...W,...B$(W)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type:Q==="unknown"?W.type:Q,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(X&&Q==="subagent")return{active:[...$.active,...$.pending.filter(Y).map(z)],pending:$.pending.filter((W)=>!Y(W))};return{active:V?$.active.map((W)=>Y(W)?z(W):W):$.active,pending:X?$.pending.map((W)=>Y(W)?z(W):W):$.pending}}let H={id:Z.task_id,displayId:Z.tool_use_id??Z.task_id,toolUseId:Z.tool_use_id,type:Q,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...mV(Q)?{isBackgrounded:!0}:{}};return Q==="subagent"||mV(Q)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function J6($,Z){let J=$.active.some((V)=>V.id===Z.task_id),Q=$.pending.some((V)=>V.id===Z.task_id);if(!J&&!Q)return $;let Y=(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?Y(V):V):$.active,pending:Q?$.pending.map((V)=>V.id===Z.task_id?Y(V):V):$.pending}}function Q6($,Z){let J=$.pending.findIndex((X)=>X.id===Z.task_id),Q=Z.patch;if(Q.is_backgrounded===!0&&J>=0){let X=$.pending[J],H={...X,isBackgrounded:!0,status:Q.status??X.status,description:Q.description??X.description,error:Q.error??X.error,endTime:Q.end_time??X.endTime};return{active:[...$.active,H],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Y||V){let X=(H)=>({...H,status:Q.status??H.status,description:Q.description??H.description,error:Q.error??H.error,isBackgrounded:Q.is_backgrounded??H.isBackgrounded,endTime:Q.end_time??H.endTime});return{active:Y?$.active.map((H)=>H.id===Z.task_id?X(H):H):$.active,pending:V?$.pending.map((H)=>H.id===Z.task_id?X(H):H):$.pending}}return $}function Y6($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function m3($,Z,J=Date.now()){let Q=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Y)=>Y.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Y)=>Y.id!==Z.task_id)};if($.active.some((Y)=>Y.id===Z.task_id))return{active:$.active.map((Y)=>Y.id===Z.task_id?{...Y,status:Q,usage:Z.usage??Y.usage,summary:Z.summary??Y.summary,endTime:Y.endTime??J}:Y),pending:$.pending};return $}function g3($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>zq){J=Q+1;break}return J===0?$:$.slice(J)}function Wq($,Z){let J=(Q)=>typeof Q==="string"?Q:"";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 Gq($,Z){let Q=((typeof $==="string"?$:Array.isArray($)?$.map((Y)=>typeof Y?.text==="string"?Y.text:JSON.stringify(Y)).join(`
95
+ `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Q.slice(0,80)}`:Q.slice(0,80)}function V6($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((W)=>W.toolUseId===Z?{...W,steps:g3([...W.steps,{toolUseId:J,tool:Q,brief:`${Q} ${Wq(Q,Y)}`.trim()}])}:W);return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function X6($,Z,J,Q,Y,V){let X=$.active.some((W)=>W.id===Z),H=$.pending.some((W)=>W.id===Z);if(!X&&!H)return $;let z=(W)=>W.map((G)=>{if(G.id!==Z)return G;if(Y==="started")return{...G,steps:g3([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()}])};let K=!1,_=G.steps.map((L)=>{if(K||L.toolUseId!==J)return L;return K=!0,{...L,brief:V?`${L.brief} ${V}`:L.brief}});if(!K&&V)_.push({toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()});return{...G,steps:g3(_)}});return{active:X?z($.active):$.active,pending:H?z($.pending):$.pending}}function H6($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((W)=>{if(W.toolUseId!==Z)return W;let G=!1,K=W.steps.map((_)=>{if(G||_.toolUseId!==J)return _;return G=!0,{..._,brief:`${_.brief} → ${Gq(Q,Y)}`}});return{...W,steps:g3(K)}});return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function dV($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of Kq)if(Z<V.limit)return{label:V.label,nextDelayMs:V.limit-Z};let J=600000,Q=Math.floor((Z-600000)/J),Y=600000+(Q+1)*J;return{label:`${U0((Q+1)*600,"down")}+`,nextDelayMs:Y-Z}}function w2($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=e7){let Q=Math.floor((J-e7)/pV),Y=e7+(Q+1)*pV;return{label:`${U0((10+Q*5)*60,"down")}+`,nextDelayMs:Y-J}}return{label:U0(Math.floor(J/1000)),nextDelayMs:lV}}return dV($)}function cV($){return $.subagentType??$.workflowName??$6[$.type]}function Bq($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function _q($){let Z=[`**${$6[$.type]}**${cV($)!==$6[$.type]?` · ${cV($)}`:""}${B$($)?` · 用时 ${U0(Bq($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Z.push(`⚠ ${$.error}`);if($.summary)Z.push("",`**${B$($)?"结果":"进度"}**`,uV($.summary,8000));if($.prompt)Z.push("","**任务说明**",uV($.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 uV($,Z){return $.length<=Z?$:`${$.slice(0,Z)}
97
+ _这里只显示预览。_`}function p3($){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 z6($){return{tag:"collapsible_panel",element_id:t4.panel($.id),header:{title:{tag:"plain_text",content:p3($)}},expanded:!1,elements:[{tag:"markdown",element_id:t4.body($.id),content:_q($)}]}}var t4,zq=1000,$6,Kq,lV=1000,e7=600000,pV=300000;var W6=O(()=>{C0();b3();t4={panel:($)=>`bg_${gV($)}`,body:($)=>`bgb_${gV($)}`};$6={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"},Kq=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as jq}from"node:events";import{join as Lq,isAbsolute as qq,extname as Fq,basename as Pq}from"node:path";import{readFile as Dq}from"node:fs/promises";function Uq($){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 c3=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),G6,K6;var iV=O(()=>{G0();C1();p4();h();G6={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};K6=class K6 extends jq{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=c3();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"};F0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new E3({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:Lq($.managedSkillPluginPath,"skills")}:{},...$.runtimeOptions}),this.runtime.on("notification",(Q)=>{if(!this.sessionId&&Q.method!=="failure"){this.earlyNotifications.push(Q);return}if(this.terminalError)return;try{this.onNotification(Q)}catch(Y){this.fail(Y)}}),this.runtime.on("failure",(Q)=>this.fail(Q)),this.runtime.on("exit",(Q)=>this.emit("exit",{...Q,expected:Q.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(G6).find((Q)=>G6[Q]===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)=>!qq(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
+ `)}],Q=new Set([...Z,...Array.from($.matchAll(/\[file: ([^\]\r\n]+)\]/g),(V)=>V[1])]),Y=new Set([".png",".jpg",".jpeg",".webp",".gif"]);for(let V of Q){if(!Y.has(Fq(V).toLowerCase()))continue;let X=await Dq(V);J.push({type:"image",mediaType:Uq(X),name:Pq(V),data:X.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 Q=String($),Y=this.questionInputs.get(Q);if(!Y)throw Error(`unknown DSH question: ${Q}`);let V=J?.updatedInput?.answers,X=Z==="allow"?Y.map((H)=>{let z=V?.[H.question];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${H.question}`);let W=H.options?.find((G)=>G.label===z);return{id:H.id,selected:W?[z]:[],...W?{}:{custom:z}}}):void 0;this.runtime.request("question/answer",{id:Q,answers:X,...Z==="deny"?{error:J?.denyMessage??"User declined the question"}:{}}).then(()=>{this.questionInputs.delete(Q),this.emit("tool_result",{tool_use_id:Q,content:JSON.stringify({answers:X}),is_error:Z==="deny",parentToolUseId:null})}).catch((H)=>this.fail(H))}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(!q0(Z))throw Error(`invalid DSH effort: ${Z}`);if(await this.initializationPromise(),await this.runtime.request("session/model",{model:$,effort:Z},null),!this.busy)this.lastModel=$,this.lastEffort=Z}async compactThread(){if(await this.initializationPromise(),await this.runtime.request("session/compact",{},null)===null)throw new S1}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={...c3(),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 Q of this.frames.keys())if(Q.startsWith(`${Z.sessionId}:`))this.frames.delete(Q);return;case"session.status":return;case"question":{this.questionInputs.set(Z.id,Z.questions);let Q={questions:Z.questions.map((Y)=>({...Y,question:Y.detail?`${Y.question}
99
+
100
+ ${Y.detail}`:Y.question}))};this.questionInputs.set(Z.id,Q.questions),this.emit("tool_use",{id:Z.id,name:"AskUserQuestion",input:Q,parentToolUseId:null}),this.emit("can_use_tool",{request_id:Z.id,tool_use_id:Z.id,tool_name:"AskUserQuestion",input:Q});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 Q=Z.frame,Y=`${Z.sessionId}:${Q.attemptId}`;if(Q.type==="start"){this.frames.set(Y,{revision:Q.revision,nextIndex:0});return}let V=this.frames.get(Y);if(!V||V.revision+1!==Q.revision||V.nextIndex!==Q.index)throw Error("DSH assistant stream sequence mismatch");if(V.revision=Q.revision,Q.type==="end"){if(this.frames.delete(Y),!J)this.emit("assistant_block_stop",{parentToolUseId:null});return}if(Q.type!=="chunk")throw Error(`unknown DSH assistant frame: ${Q.type}`);V.nextIndex++;let X=Q.chunk;if(X.type==="text-delta"){if(J)this.childText.set(Z.sessionId,(this.childText.get(Z.sessionId)??"")+X.text);this.emit("assistant_text",{text:X.text,parentToolUseId:J?Z.sessionId:null})}else if(X.type==="block-end"&&X.block.type==="text"&&!J)this.emit("assistant_block_stop",{parentToolUseId:null});else if(X.type==="usage"&&!J)this.observeUsage(X.usage);return}case"session.event":{let Q=Z.event,Y=Q.data;if(!Q||!Y||typeof Q.type!=="string")throw Error("invalid DSH session event");if(Q.type==="turn/start"&&!J)this.busy=!0,this.startedAt=Date.now(),this.lastUsage=null,this.lastResult=c3(),this.emit("scheduled_turn_input",{text:"DeepSeek Harness 继续执行",promptId:`dsh-turn-${Y.turn}`}),this.emit("turn_started",{turn_id:String(Y.turn),thread_id:this.sessionId});else if(Q.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(Q.type==="request/header"&&!J&&Y.header?.config)this.lastModel=Y.header.config.model,this.lastEffort=Y.header.config.reasoningEffort,this.lastContextWindow=this.models.find((V)=>V.model===this.lastModel)?.contextWindow??null;else if(Q.type==="tool/call"){let V=JSON.parse(Y.arguments),X=G6[Y.name]??Y.name;if(["read","write","edit"].includes(Y.name)&&V.path)V.file_path=V.path;this.toolInputs.set(Y.callId,{name:X,input:V}),this.emit("tool_use",{id:Y.callId,name:X,input:V,parentToolUseId:J?Z.sessionId:null})}else if(Q.type==="tool/result"){let V=Y.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(Q.type==="todo/write"&&!J)this.emit("turn_plan_updated",{threadId:this.sessionId,explanation:null,plan:Y.todos.map((V)=>({step:V.content,status:V.status==="in_progress"?"inProgress":V.status}))});else if(Q.type==="compaction/start"&&!J)this.emit("context_compacted",{threadId:this.sessionId,phase:"start",sourceType:"dsh"});else if(Q.type==="compaction/end"&&!J)if(Y.error)this.emit("error",Error(`DSH compaction: ${Y.error}`));else this.emit("context_compacted",{threadId:this.sessionId,phase:"end",sourceType:"dsh"});else if(Q.type==="goal/change"&&!J)if(Y.operation==="clear")this.emit("thread_goal_cleared",{threadId:this.sessionId});else this.emit("thread_goal_updated",{threadId:this.sessionId,objective:Y.goal.objective,status:Y.goal.phase,tokenBudget:null,tokensUsed:Number.NaN,timeUsedSeconds:Number.NaN});else if(Q.type==="turn/end"&&J&&this.children.has(Z.sessionId))this.settledChildren.add(Z.sessionId),this.emit("bg_task_settled",{task_id:Z.sessionId,status:Y.reason.kind==="completed"?"completed":Y.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 Q=Z.event,Y=Q.data.reason;this.lastCompletedTurnId=String(Q.seq),this.lastResult={...c3(),duration_ms:Date.now()-this.startedAt,num_turns:1,usage:this.lastUsage,subtype:Y.kind,is_error:Y.kind!=="completed"},this.emit("result",{...this.lastResult,...Y.kind!=="completed"?{error:Y.error?.message??`DSH turn ended: ${Y.kind}`,errors:[Y.error?.message??`DSH turn ended: ${Y.kind}`]}:{},checkpoint:{provider:"dsh",kind:"event",id:String(Q.seq),source:{provider:"dsh",sessionId:this.sessionId,cwd:this.opts.workDir}}});return}default:B(`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[Q,Y]of Object.entries(Z))if(Y!==void 0){let V=Q;J[V]=(J[V]??0)+Y}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 Y1($){return $.startsWith("claude:")?$:`claude:${$}`}function e4($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(g.claude.models,Z))return g.claude.models[Z]?.model?.trim()||"opus";return Z}var B6=O(()=>{S0()});import{existsSync as Mq,readFileSync as Aq}from"node:fs";function _6(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:LY}function Z9(){if($9!==null)return $9;try{$9=Mq(_6())?JSON.parse(Aq(_6(),"utf8")):{}}catch($){B(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),$9={}}return $9??{}}function Nq(){try{o(_6(),Z9())}catch($){B(`context-window-observe: cache write MISS (${$?.message??$})`)}}function j6($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function nV($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=j6($,Z),Y=Z9()[Q];if(Y===J)return;Z9()[Q]=J,Nq(),B(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function u3($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=Z9()[j6($,Z)];return J!=null&&J<Oq?Z:`${Z}[1m]`}function y2($,Z){return Z9()[j6($,Z)]}var Oq=1e6,$9=null;var J9=O(()=>{V0();h();x0()});var U6={};v$(U6,{toolsFromProfile:()=>HX,settingSourcesFromProfile:()=>XX,resolveClaudeExecutableConfig:()=>D6,resetClaudeContextWindowCache:()=>Cq,readProjectMcpServers:()=>zX,readLastCallUsageFromTranscript:()=>QX,claudeTranscriptPath:()=>n3,claudeTranscriptDir:()=>i3,claudeManagedSkillOptions:()=>ZX,buildClaudeSpawnPath:()=>JX,assertClaudeCodeAvailable:()=>P6,ClaudeAgentProcess:()=>a3,CLAUDE_PERMISSION_MODE:()=>VX});import{existsSync as rV,readFileSync as eV}from"node:fs";import{homedir as d3}from"node:os";import{spawn as Rq}from"cross-spawn";import{delimiter as aV,join as b1}from"node:path";import{EventEmitter as Tq}from"node:events";function ZX($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function Eq($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function xq($){let Z=Rq($.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 P6(){D6(),U7("claude","@anthropic-ai/claude-agent-sdk")}function D6($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?g.claude.bin:$.configuredBin;if(J){if(!($.exists??rV)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&Eq(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:xq,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function JX(){if(process.platform==="win32")return process.env.PATH??"";let $=[b1(d3(),".local","npm-global","bin"),b1(d3(),".local","bin"),b1(d3(),".bun","bin"),...(process.env.PATH??"").split(aV),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(aV)}function Sq($){let Z=E2($);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 oV($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function i3($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||b1(d3(),".claude");return b1(J,"projects",Z)}function n3($,Z){return b1(i3($),`${Z}.jsonl`)}function QX($){let Z;try{Z=eV($,"utf8")}catch{return null}let J=Z.split(`
101
+ `);for(let Q=J.length-1;Q>=0;Q--){let Y=J[Q].trim();if(!Y)continue;try{let V=JSON.parse(Y);if(V?.type==="assistant"&&V?.message?.usage){let X=V.message.usage;if((X.input_tokens??0)+(X.cache_read_input_tokens??0)+(X.cache_creation_input_tokens??0)+(X.output_tokens??0)>0)return X}}catch{}}return null}function sV($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function Cq(){q6.clear()}function bq($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Y of Object.values($)){if(!Y||typeof Y!=="object")continue;let V=Y;Z.input_tokens=(Z.input_tokens??0)+v2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+v2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+v2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+v2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+v2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=v2(V.contextWindow??V.context_window);if(X>0)J=Math.max(J??0,X)}let Q=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Q<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Q,{usage:Z,contextWindow:J}}function l3($){return{...$}}function L6($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function kq($,Z){let J=$?{...$}:{},Q=(Y)=>{let V=Z[Y];if(typeof V!=="number"||!Number.isFinite(V))return;J[Y]=(J[Y]??0)+V};return Q("total_tokens"),Q("input_tokens"),Q("output_tokens"),Q("reasoning_output_tokens"),Q("cache_creation_input_tokens"),Q("cache_read_input_tokens"),J}function v2($){return typeof $==="number"&&Number.isFinite($)?$:0}function YX($){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 wq($){let Z=YX($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Q=J.map((Y)=>{if(typeof Y==="string")return Y;if(Y&&typeof Y==="object"&&typeof Y.text==="string")return Y.text;return JSON.stringify(Y)}).filter(Boolean);if(Q.length>0)return Q.join(`
103
+ `)}}catch{}return Z}function yq($){return`server_tool:${$}`}function vq($){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 fq($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function hq($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[e$];return{id:Y1($.value),model:Y1($.value),displayName:$.displayName||Y1($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(e$)?e$:Z[0]}}function XX($){if(!$?.settingSources)return[...tV];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...tV]}function HX($){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 zX($){let Z=b1($,".mcp.json"),J;try{J=eV(Z,"utf8")}catch(Q){if(Q.code!=="ENOENT")B(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Q}`);return}try{let Q=JSON.parse(J);if(Q&&typeof Q==="object"&&Q.mcpServers&&typeof Q.mcpServers==="object")return Q.mcpServers;B(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Q){B(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Q}`);return}}function Iq($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>gq(Q)).filter((Q)=>Q!==null)}function gq($){let Z=$&&typeof $==="object"?$:{question:$},J=F6(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=mq(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Q,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function mq($){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 Q=J,Y=F6(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let V=F6(Q.description,Q.detail,Q.preview);Z.push(V?{label:Y,description:V}:{label:Y})}return Z}function F6(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var $X,q6,VX="default",tV,a3;var f2=O(()=>{A2();S0();h();G0();B6();J9();$X=class $X{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($))}};q6=new Map;tV=["project","local"];a3=class a3 extends Tq{provider="claude";tokenSourceId;opts;input=new $X;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?Y1($.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 $=e4(this.opts.model),Z=this.opts.profile;if(Z)B(`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??XX(Z),Q=ZX(J,this.opts.managedSkillPluginPath),Y=HX(Z),V=Z?.strictMcp===!0,X=Z?.loadProjectMcp!==!1?zX(this.opts.workDir):void 0;try{let H=D6(),{query:z}=await cY();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:JX(),...g.claude.env,...this.opts.hostEnv??{}},G=this.opts.transformEnv?this.opts.transformEnv(W):W;if(G.CLAUDE_CODE_ENABLE_TODO_TOOLS="1",this.opts.effort==="default")G.CLAUDE_CODE_EFFORT_LEVEL="unset";B(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${H.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}:{},...H.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:H.pathToClaudeCodeExecutable}:{},...H.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:H.spawnClaudeCodeProcess}:{},permissionMode:VX,env:G,settingSources:[...J],...this.opts.settings?{settings:this.opts.settings}:{},...Q,tools:Y,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...V?{strictMcpConfig:!0}:{},...X?{mcpServers:X}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(K,_,L)=>this.canUseTool(K,_,L),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(K)=>{let _=K.trim();if(_)B(`claude-agent-process[stderr]: ${_}`)}}})}catch(H){let z=H instanceof Error?H:Error(String(H));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(H){this.initializationError=H instanceof Error?H:Error(String(H)),this.emit("error",this.initializationError),await this.kill()}}sendUserText($,Z=[]){if(!this.alive){B("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).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(Q){let Y=Q instanceof Error?Q:Error(String(Q));B(`claude-agent-process: sendUserText failed: ${Y.message}`),this.failTurnStart(Y)}}sendInterrupt(){this.query?.interrupt().catch(($)=>B(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Q=this.pendingPermissions.get(String($));if(!Q){B(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Q.cleanup?.(),Z==="allow")Q.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Q.resolve({behavior:"deny",message:J?.denyMessage??""})}sendHookResponse($,Z={}){B("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 B(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw B(`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(hq)}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=e4($);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)");try{await this.query.setModel(J)}catch(Q){throw this.lastModel=null,this.lastEffort=null,new T2(`模型设置未确认:${Q instanceof Error?Q.message:String(Q)}`,null,{cause:Q})}this.opts.model=$,this.lastModel=J?Y1($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Q){throw new T2(`模型已切换为 ${$},但思考档位未确认:${Q instanceof Error?Q.message:String(Q)}`,$,{cause:Q})}this.opts.effort=Z,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,Q=()=>{this.off("context_compacted",Y),this.off("assistant_text",V),this.off("exit",X),this.off("error",H)},Y=()=>{if(J)return;J=!0,Q(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new S1)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},H=(z)=>{if(J)return;J=!0,Q(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Y),this.on("assistant_text",V),this.once("exit",X),this.once("error",H)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=Iq(Z);if(Q.length===0)return B("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Y={...Z,questions:Q},V=`claude_perm_${++this.requestCounter}`,X=J.toolUseID||V,H={request_id:V,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},z=new Promise((W)=>{let G=(_)=>{J.signal.removeEventListener("abort",K),W(_)},K=()=>{if(!this.pendingPermissions.delete(V))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:G,request:H})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",H),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){B(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}B(`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(),B(`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,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Q(!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:B(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=Y1($.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":B(`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){B("claude-agent-process: invalid thinking_tokens estimate");return}this.lastThinkingTokens=$.estimated_tokens,this.emit("thinking_progress",{estimatedTokens:$.estimated_tokens});return;case"permission_denied":B(`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){B("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){B(`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:B(`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=Y1(Z.model);let Q=Array.isArray(Z?.content)?Z.content:[];for(let Y of Q){if(!Y||typeof Y!=="object")continue;if(Y.type==="text"&&typeof Y.text==="string"&&Y.text.length>0){let V=vq(Y.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(fq(Y.text))continue;let X=$.uuid??Z?.id;this.emit("assistant_text",{uuid:X,text:Y.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:X,parentToolUseId:J})}else if(Y.type==="tool_use"&&typeof Y.id==="string"&&typeof Y.name==="string")this.emitToolUseOnce(Y.id,Y.name,Y.input??{},J);else if(Y.type==="server_tool_use"&&typeof Y.id==="string"&&typeof Y.name==="string")this.emitToolUseOnce(Y.id,yq(Y.name),{tool:Y.name,input:this.serverToolInput(Y.name,Y.input??{})},J);else if(Y.type==="tool_result"&&typeof Y.tool_use_id==="string")this.emitToolResultOnce(Y.tool_use_id,wq(Y.content),Y.is_error===!0,J)}}emitToolUseOnce($,Z,J,Q){if(this.emittedToolUseIds.has($))return;if(this.emittedToolUseIds.add($),!Z.trim())B(`claude-agent-process: tool_use ${$} has an empty name`),Z="MISS";this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Q})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Q=this.pendingServerToolInputs.findIndex((Y)=>Y.name===$);if(Q>=0){let[Y]=this.pendingServerToolInputs.splice(Q,1);return Y.input}return J}emitToolResultOnce($,Z,J,Q){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Q})}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 Q of J){if(!Q||typeof Q!=="object")continue;if(Q.type!=="tool_result"||typeof Q.tool_use_id!=="string")continue;let Y=$.tool_use_result,V=YX(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
106
+ `):"",H=V||X;this.emitToolResultOnce(Q.tool_use_id,H,Q.is_error===!0||Y?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=Sq($.usage),J=$.modelUsage??$.model_usage,Q=bq(J);if(!Z&&!Q.usage)B(`claude-agent-process: result usage missing rootKeys=${L6($).join(",")||"-"} usageKeys=${L6($.usage).join(",")||"-"} modelUsageKeys=${L6(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=l3(Q.usage),this.lastTotalUsage=l3(Q.usage);else if(Z)this.cumulativeUsageFromResults=kq(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=l3(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?l3(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let H=sV(this.opts.model,this.tokenSourceId);if(q6.set(H,Q.contextWindow),this.tokenSourceId)for(let[z,W]of Object.entries(J??{})){let G=W?.contextWindow;if(typeof G==="number"&&G>0)nV(this.tokenSourceId,z,G)}}this.lastContextWindow=q6.get(sV(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=n3(this.opts.workDir,this.sessionId??""),V=QX(Y);if(this.lastContextTokens=oV(V)??(rV(Y)?oV(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 X=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:X,is_error:$.is_error===!0||X!=="success"},this.emit("result",{subtype:X,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??X)}:{},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 KX={};v$(KX,{waitForTokenSourceModelRefresh:()=>w1,tokenSourceRuntimeModels:()=>V1,tokenSourceRuntimeModel:()=>N$,tokenSourceRegistryRevision:()=>A6,tokenSourceProcessRevision:()=>I2,tokenSourceFactories:()=>k1,setDefaultTokenSource:()=>R6,scrubDshEnv:()=>Q9,scrubAnthropicEnv:()=>h0,resetTokenSourceRegistry:()=>T6,registerTokenSourceFactory:()=>j0,registerTokenSource:()=>O6,refreshAllTokenSourceModels:()=>V9,pendingTokenSourceModelRefresh:()=>g2,listTokenSourcesByAgent:()=>GX,listTokenSources:()=>J$,listEnabledTokenSourcesByAgent:()=>N6,getTokenSourceForAccount:()=>H0,getTokenSource:()=>I0,ANTHROPIC_ENV_KEYS:()=>s3});function h0($){let Z={...$};for(let J of s3)delete Z[J];return delete Z.LODESTAR_PACKY_API_KEY,Z}function Q9($){let Z=h0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function V1($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function N$($,Z){let J=(Q)=>$.agent==="claude"?Q?.replace(/\[1m\]$/,""):Q;return V1($).find((Q)=>J(Q.model)===J(Z))}function I2($,Z){let J=$?.spawnRevision??null,Q=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Q===void 0?J:JSON.stringify([J,Q])}function j0($){WX.set($.kind,$)}function k1(){return[...WX.values()]}function A6(){return M6}function O6($,Z){if(Y9.set($.id,$),Z?.default||o3===null)o3=$.id}function I0($){return $?Y9.get($):void 0}function H0($,Z="default"){let J=I0($);return J?.forAccount?J.forAccount(Z):J}function J$(){return[...Y9.values()]}function GX($){return J$().filter((Z)=>Z.agent===$)}function N6($){return GX($).filter((Z)=>Z.enabled)}function R6($){if(Y9.has($))o3=$}function T6(){Y9.clear(),o3=null,M6++}function V9(){let $=M6;if(h2?.generation===$)return h2.promise;let Z=Promise.allSettled(J$().map(async(J)=>{await J.refreshModels(),B(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(h2?.promise===Z)h2=null});return h2={generation:$,promise:Z},Z}function g2(){return h2?.promise??null}async function w1(){let $;while($=g2())await $}var s3,WX,Y9,o3=null,M6=0,h2=null;var e=O(()=>{h();s3=["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"];WX=new Map;Y9=new Map});import{createHash as pq}from"node:crypto";class n0{now;entries=new Map;constructor($=()=>Date.now()){this.now=$}read($,Z){let J=this.entries.get($);if(J?.pending)return J.pending;if(J&&this.now()<J.retryAt)return J.failed?Promise.reject(J.error):Promise.resolve(J.value);J??={failed:!1,failures:0,retryAt:0},this.entries.set($,J);let Q=J,Y=(X,H=0)=>{Q.failures=X?0:Q.failures+1;let z=X?X1:Math.min(cq,X1*2**Math.min(Q.failures-1,3));Q.retryAt=this.now()+Math.max(z,Number.isFinite(H)?H:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Q)Q.value=X,Q.failed=!1,Q.error=void 0,Y(X.state==="ok"||X.state==="not_applicable",X.retryAfterMs);return X},(X)=>{if(this.entries.get($)===Q)Q.value=void 0,Q.failed=!0,Q.error=X,Y(!1);throw X}).finally(()=>{if(Q.pending===V)Q.pending=void 0});return Q.pending=V,V}prime($,Z){this.entries.set($,{value:Z,failed:!1,failures:0,retryAt:this.now()+X1})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function Q$($,Z,J){return pq("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function R$($,Z=Date.now()){let J=$.get("retry-after");if(!J)return;let Q=Number(J),Y=Number.isFinite(Q)?Q*1000:Date.parse(J)-Z;return Number.isFinite(Y)&&Y>=0?Y:void 0}function m2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var X1=60000,cq=300000;var m$=()=>{};import{spawn as uq}from"cross-spawn";import{EventEmitter as lq}from"node:events";import{StringDecoder as dq}from"node:string_decoder";import{createHash as iq}from"node:crypto";function x6($,Z){if(e3.set($,Z),Z.state==="ok")X9.set($,Z);else if(Z.state==="no_credentials"||Z.state==="auth_failed")X9.delete($)}function _X($,Z,J=(Q)=>new H1({accountId:Q})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Q=t3.get($);if(Q)return Q.key===Z?Q.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Y=Promise.resolve().then(async()=>{let V=J($),X,H;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");p2($);let W;try{W=await y1(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{p2($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(W?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(W)};请用 codex-accounts 核对后再操作`);let G=Y$.get($),K;try{K=await $8.read($,async()=>S6(await b6(()=>V.request("account/rateLimits/read",{})),z.planType))}catch(_){K={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(Y$.get($)!==G)K={state:"auth_failed"};else x6($,K);if(K.state!=="ok")B(`codex-reset: ${$} quota refresh failed: ${K.state==="network"?K.reason:K.state}`);X={outcome:W.outcome,usage:K}}catch(z){H=z,B(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let W=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(B(`codex-reset: ${$}: ${W}`),X)X.cleanupError=W;else throw AggregateError([H,z],`${String(H)};${W}`)}if(!X)throw H;return X}).finally(()=>{if(t3.get($)?.promise===Y)t3.delete($)});return t3.set($,{key:Z,promise:Y}),Y}function jX($,Z){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout after ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Y),J(V)},(V)=>{clearTimeout(Y),Q(V)})})}function nq($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function r3($){if(!$)return null;return{percent:nq($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function aq($){let Z=r3($?.primary),J=r3($?.secondary),Q=(V)=>V?.durationMins!=null&&V.durationMins>0&&V.durationMins<=720,Y=(V)=>V?.durationMins!=null&&V.durationMins>720;if(Q(Z)&&Y(J))return{fiveHour:Z,weekly:J};if(Q(J)&&Y(Z))return{fiveHour:J,weekly:Z};if(Y(Z)&&!J)return{fiveHour:null,weekly:Z};if(Y(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function oq($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Q=[];for(let[Y,V]of J){let{fiveHour:X,weekly:H}=aq(V);if(!X&&!H)continue;Q.push({limitId:Y,limitName:V?.limitName??null,fiveHour:X,weekly:H,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function sq($){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 LX($,Z=p){let J=sq($),Q=e3.get(Z),Y=Q?.state==="ok"?Q.buckets??[]:[],V=Y.filter((X)=>BX(X.fiveHour,r3($?.primary))&&BX(X.weekly,r3($?.secondary)));if(Y.length>0&&V.length===0)B(`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)B(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${V[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function BX($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function tq($){let Z=new H1({accountId:$});try{await Z.initialize("lodestar-usage");let Q=(await jX(Z.request("account/read",{}),E6))?.account;if(!Q)return{state:"no_credentials"};if(Q.type!=="chatgpt")return{state:"auth_failed"};let Y=await b6(()=>Z.request("account/rateLimits/read",{}));return S6(Y,Q.planType)}catch(J){if(B(`usage: codex app-server usage failed: ${J?.message??J}`),J8(J))return{state:"auth_failed"};if(m2(J))return{state:"rate_limited"};return{state:"network",reason:J?.message??String(J)}}finally{await Z.close()}}function S6($,Z){let{buckets:J,defaultLimitId:Q}=oq($),Y=J.find((X)=>X.limitId===Q)??J[0];if(!Y)return{state:"network",reason:"empty rate limit response"};let V=Z??$?.rateLimits?.planType??void 0;return Y.fiveHour=l7(V,Y.fiveHour),{state:"ok",subscriptionType:V,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:iq("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:Y.rateLimitReachedType,spendControlReached:Y.spendControlReached,fiveHour:Y.fiveHour,weekly:Y.weekly,buckets:J,defaultLimitId:Y.limitId,resetCredits:Number.isInteger($?.rateLimitResetCredits?.availableCount)&&$.rateLimitResetCredits.availableCount>=0?$.rateLimitResetCredits.availableCount:null,fetchedAt:Date.now()}}function qX($=p){return X9.get($)??null}function FX($=p){let Z=qX($);return Z&&Date.now()>=Z.fetchedAt&&Date.now()-Z.fetchedAt<X1?Z:null}function C6($=p){let Z=Y$.get($)??0;return{accountId:$,read:()=>(Y$.get($)??0)===Z?qX($):null}}function c2($=p){let Z=Y$.get($)??0;return $8.read($,async()=>{try{return await tq($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(J8(J))return{state:"auth_failed"};if(m2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((Y$.get($)??0)!==Z)return{state:"auth_failed"};return x6($,J),J})}function Z8($,Z=p){let J=Y$.get(Z)??0;return $8.read(Z,async()=>{try{let Q=S6(await b6(()=>$("account/rateLimits/read",{})));if(Q.state!=="ok")B(`usage: refresh from connection: ${Q.state==="network"?Q.reason:Q.state}`);return Q}catch(Q){throw B(`usage: refresh from connection failed: ${Q instanceof Error?Q.message:String(Q)}`),Q}}).then((Q)=>{if((Y$.get(Z)??0)!==J)return null;if((Y$.get(Z)??0)===J)x6(Z,Q);return Q}).catch((Q)=>{if((Y$.get(Z)??0)===J){if(e3.delete(Z),J8(Q))X9.delete(Z)}return null})}function DX(){return PX}function p2($){PX++,Y$.set($,(Y$.get($)??0)+1),e3.delete($),X9.delete($),$8.invalidate($)}function J8($){let Z=$ instanceof Error?$.message:String($);return/\b(?:401|403)\b|unauthori[sz]ed|not authenticated|authentication (?:failed|required)|not logged in/i.test(Z)}function b6($){return y1($,"额度查询",{retryRateLimits:!1})}async function y1($,Z="额度查询",J={}){let Q=[1000,4000];for(let Y=0;;Y++)try{return await jX($(),E6)}catch(V){let X=V instanceof Error?V.message:String(V);if(J8(V))throw V;if(J.retryRateLimits===!1&&m2(V))throw V;if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(X))throw V;if(Y>=Q.length)throw Error(`Codex ${Z}失败(已尝试 ${Y+1} 次):${X}`,{cause:V});B(`usage: ${Z} retry ${Y+1}/${Q.length} in ${Q[Y]}ms: ${X}`),await new Promise((z)=>setTimeout(z,Q[Y]))}}var E6=1e4,e3,X9,$8,t3,H1,Y$,PX=0;var T$=O(()=>{J1();h();S0();f0();m$();e3=new Map,X9=new Map,$8=new n0;t3=new Map;H1=class H1 extends lq{proc;buf="";decoder=new dq("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??p;this.proc=uq($.bin??a4(),["app-server","--listen","stdio://",...$.args??y.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??y.env(Z,{...process.env,...g.codex.env},!0,$.login)}),this.exitPromise=new Promise((Q)=>{this.resolveExit=Q}),this.proc.stdout.on("data",(Q)=>this.onStdout(Q)),this.proc.stderr.on("data",(Q)=>{let Y=Q.toString().trim();if(Y)B(`usage[codex stderr]: ${Y}`)});let J=(Q)=>{if(!this.alive)return;this.alive=!1;for(let[Y,V]of this.pending)clearTimeout(V.timer),V.reject(Error(`${Q.message}; pending ${V.method} id=${Y}`));this.pending.clear(),this.resolveExit(),this.emit("exit"),this.emit("closed",Q)};this.proc.on("error",(Q)=>J(Error(`codex app-server spawn failed: ${Q.message}`))),this.proc.stdin.on("error",(Q)=>{B(`usage: codex stdin failed: ${Q.message}`),this.emit("protocolError",Q)}),this.proc.on("close",(Q,Y)=>{J(Error(`codex app-server exited code=${Q} signal=${Y}`))}),$1(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
108
+ `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Q;try{Q=JSON.parse(J)}catch{this.emit("protocolError",Error("Codex app-server returned invalid JSON"));continue}if(!Q||typeof Q!=="object"||Array.isArray(Q)){this.emit("protocolError",Error("Codex app-server returned invalid RPC object"));continue}let Y=Object.prototype.hasOwnProperty.call(Q,"id");if(typeof Q.method==="string"){if(!Y)this.emit("notification",Q.method,Q.params);else B(`usage: unsupported Codex server request: ${Q.method}`),this.proc.stdin.write(JSON.stringify({id:Q.id,error:{code:-32601,message:`Unsupported server request: ${Q.method}`}})+`
109
+ `);continue}if(!Y||!Object.prototype.hasOwnProperty.call(Q,"result")&&!Object.prototype.hasOwnProperty.call(Q,"error")){this.emit("protocolError",Error("Codex app-server returned an incomplete RPC response"));continue}let V=this.pending.get(Q.id);if(!V)continue;if(this.pending.delete(Q.id),clearTimeout(V.timer),Q.error)V.reject(Error(JSON.stringify(Q.error)));else V.resolve(Q.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"})+`
110
+ `,(Q)=>Q?J(Q):Z())})}isAlive(){return this.alive}request($,Z,J=E6){let Q=this.nextId++;return new Promise((Y,V)=>{if(!this.alive){V(Error(`codex app-server is not alive; cannot request ${$}`));return}let X=setTimeout(()=>{if(!this.pending.delete(Q))return;V(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Q,{resolve:Y,reject:V,method:$,timer:X});try{this.proc.stdin.write(JSON.stringify({id:Q,method:$,params:Z})+`
111
+ `,(H)=>{if(!H)return;let z=this.pending.get(Q);if(!z)return;this.pending.delete(Q),clearTimeout(z.timer),z.reject(Error(`codex app-server write failed for ${$}: ${H.message}`))})}catch(H){this.pending.delete(Q),clearTimeout(X),V(H instanceof Error?H:Error(String(H)))}})}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)}}};Y$=new Map});import{existsSync as rq,readFileSync as eq}from"node:fs";class UX{deps;constructor($){this.deps=$}blocks(){if(!rq(this.deps.stateFile))return[];let $=JSON.parse(eq(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"?n4($.usage,Z):null,Q=["fiveHour","weekly"].flatMap((H)=>{let z=J?.[H];return z?[{kind:H,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Y=d7($.usage,Z),V=JSON.stringify([$.identity,Y]),X=this.blocks().filter((H)=>H.key!==V);X.push({key:V,identity:$.identity,meter:Y,windows:Q}),o(this.deps.stateFile,{version:1,blocks:X})}async choose($){$.signal?.throwIfAborted();let Z=this.deps.accounts();if($.preferred){let J=Z.find((Q)=>Q.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 Q=await Promise.all($.map(async(j)=>{let q,P=null,N=`record:${j.id}`;if(this.deps.pendingLogin(j.id))q={state:"network",reason:"正在登录"};else try{q=J?this.deps.cachedUsage(j.id):await this.deps.usage(j.id);let D=q?.state==="ok"?q.accountFingerprint??this.deps.identity(j.id):null;if(D)N=D;else if(q?.state==="ok")P="账号身份 MISS";if(q?.state==="ok"&&!P)P=await this.deps.compatible(j.id,Z.model,Z.effort)}catch(D){q={state:"network",reason:String(D)}}return{account:j,usage:q,identity:N,reason:P}}));Z.signal?.throwIfAborted();let Y=Z.failedAccountId&&Q.find((j)=>j.account.id===Z.failedAccountId);if(Y&&Y.usage?.state==="ok")this.block({account:Y.account,usage:Y.usage,identity:Y.identity,...i7(Y.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let V=this.blocks(),X=this.deps.now(),H=new Set,z=new Map,W=Q.map(({account:j,usage:q,identity:P,reason:N})=>{let D=i7(q??{state:"network",reason:"尚无额度缓存"},Z.model,X,Z.effort);if(N)D={...D,state:"miss",score:null,reason:N};let U=z.get(P);if(z.set(P,U??j.name),U)D={...D,state:"miss",score:null,reason:`重复账号:${U}`};let M=q?.state==="ok"?d7(q,Z.model):null,T=V.find((x)=>(x.identity===P||x.identity===`record:${j.id}`)&&x.meter===M);if(T&&q?.state==="ok"&&D.state==="ready"){let x=n4(q,Z.model);if(!J&&T.windows.some((b)=>{let v=x[b.kind];return v&&v.percent!==null&&(b.percent!==null&&v.percent<b.percent||b.reset!==null&&b.reset<=X&&(v.resetsAt?.getTime()??0)>b.reset)}))H.add(T.key);else D={...D,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:j,usage:q,identity:P,...D,...U?{duplicateOf:U}:{}}});if(H.size)o(this.deps.stateFile,{version:1,blocks:V.filter((j)=>!H.has(j.key))});let G=W.filter((j)=>j.state==="ready");G.sort((j,q)=>q.score-j.score||(q.availableNow??0)-(j.availableNow??0)||j.account.id.localeCompare(q.account.id));let K=G[0]??null,_=W.filter((j)=>j.state==="exhausted"||j.state==="waiting"),L=_.length?Math.min(..._.map((j)=>j.retryAt??X+60000)):void 0;for(let j of W)B(`codex scheduler${J?" [cache]":""}: ${j.account.name} ${j.state} score=${j.score??"MISS"}${j.reason?` (${j.reason})`:""}`);return{selected:K,candidates:W,...L!==void 0?{retryAt:L}:{}}}}var Q8;var k6=O(()=>{f0();T$();e();V0();x0();h();Q8=new UX({accounts:()=>y.list(),usage:c2,cachedUsage:FX,identity:($)=>y.fingerprint($),pendingLogin:C2,now:Date.now,stateFile:jY,compatible:async($,Z,J)=>{let Q=H0("codex-sub",$);if(!Q)return"订阅来源 MISS";if(Q.modelCatalogState?.status!=="ready")await Q.refreshModels();if(!Q.enabled||Q.modelCatalogState?.status!=="ready")return Q.modelCatalogState?.error??"模型目录 MISS";let Y=N$(Q,Z);return!Y||Y.unavailableReason||J&&!Y.efforts.includes(J)?`${Z}/${J??"default"} 不可用`:null}})});import{EventEmitter as $F}from"node:events";function QF($,Z){return Z.throwIfAborted(),new Promise((J,Q)=>{let Y=()=>{clearTimeout(X),Z.removeEventListener("abort",V)},V=()=>{Y(),Q(Z.reason)},X=setTimeout(()=>{Y(),J()},$);Z.addEventListener("abort",V,{once:!0})})}var ZF="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",JF,w6=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),y6;var MX=O(()=>{f0();k6();T$();h();JF=["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"];y6=class y6 extends $F{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??w6()}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??Q8}notice($,Z=0){this.ownRetry={reason:"quota",phase:Z?"waiting":"retrying",attempt:this.retryCount,delayMs:Z,message:$},B(`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 Q=await this.scheduler().choose(J);if(delete J.failedAccountId,this.lifetime.signal.throwIfAborted(),Q.selected)return{...Q,selected:Q.selected};J.preferCachedUsage=!1;let Y=Q.candidates.map((H)=>`${H.account.name}:${H.reason??H.state}`).join(";");if(Q.retryAt===void 0){let z=Q.candidates.some((W)=>W.state==="miss"&&!W.duplicateOf)?"Codex 账号检查失败,无法自动选账号(MISS)":Q.candidates.length?"没有符合条件的 Codex 账号":"没有配置 Codex 账号";throw Error(`${z}${Y?`;${Y}`:""}`)}let V=Math.max(1000,Math.min(60000,Q.retryAt-Date.now())),X=Q.candidates.filter((H)=>H.state==="miss"&&!H.duplicateOf).length;B(`codex account: waiting for quota: ${Y}`),this.notice(`暂无可用账号 · 自动等待恢复${X?` · ${X} 个 MISS`:""}`,V),this.resolveQuotaWait(),await(this.opts.wait??QF)(V,this.lifetime.signal)}}async launch($,Z,J){this.starting=!0;let Q=await this.choose(Z,J);this.lifetime.signal.throwIfAborted();let Y=this.selected?.account.id??null,{process:V,sourceRevision:X}=this.opts.create(Q.selected.account.id,$,Q.selected.state==="manual",this.opts.model||this.lastModel||void 0,this.opts.effort??this.lastEffort??void 0);this.inner=V,this.selected=Q.selected,this.revision=X,$1(this,Q.selected.account.id,!1),this.wire(V),this.emit("codex_account_changed",{accountId:Q.selected.account.id,previousAccountId:Y,diagnostics:Q.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 H=V.initializationPromise?.();if(!H)throw Error("Codex 初始化未提供确认事务");if(await H,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 JF)$.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((Q)=>{if(!this.lifetime.signal.aborted)this.fail(Q)}).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 H=await Z8(()=>$.readRateLimits(),this.selected.account.id);if(this.lifetime.signal.throwIfAborted(),H?.state==="ok")this.selected={...this.selected,usage:H,identity:H.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 Q=$.conversationMaterializationBarrier?.();if(Q)await Q;this.lifetime.signal.throwIfAborted();let Y=$.isConversationResumable?.()===!0&&$.sessionId;if(Z.accepted&&!Y)throw Error("额度耗尽后未确认原会话落盘,不能重放已执行的任务");if(!Z.accepted&&typeof Z.rejectedInput!=="string")throw Error("额度耗尽的拒绝响应缺少原始输入");let V=Y?{kind:"resume",source:{provider:"codex",sessionId:$.sessionId,cwd:this.opts.workDir}}:this.opts.launch;if(await $.kill(),$.isAlive())throw Error("旧 Codex 进程退出未确认,不能启动下一账号");for(let H of this.backgroundTasks)this.emit("bg_task_settled",{task_id:H,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 X=Z.accepted?ZF:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(X),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...w6(),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={...w6(),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 H9($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new y6({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,_,L,j,q)=>H9({...$,model:j,effort:q,codexAccountPreference:void 0,codexManualAccount:L,codexAccountId:K,launch:_})}),sourceRevision:null}}let Z=$.codexAccountId??p,J=H0($.tokenSourceId,Z),Q=$.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexManualAccount===!0;if($.tokenSourceId&&!J)throw Error(`token source not found: ${$.tokenSourceId}`);if(J&&!J.enabled&&!Q)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(!Q&&J?.modelCatalogState?.status==="failed")throw Error(`model catalog refresh failed for ${J.id}: ${J.modelCatalogState.error??"MISS"}`);if(!Q&&(J?.modelCatalogState?.status==="idle"||J?.modelCatalogState?.status==="loading"))throw Error(`model catalog is not ready for ${J.id}: ${J.modelCatalogState.status}`);let Y=$.model||J?.defaultModel||void 0,V=I2(J,Y),X=!Q&&J&&N$(J,Y);if(!Q&&J&&Y&&!X)throw Error(`model is not present in token source ${J.id}: ${Y}`);if(!Q&&X&&(X.unavailableReason||!X.efforts.length||$.effort!==void 0&&!X.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Y}/${$.effort??"MISS"}`);let H=!Q&&J&&Y?J.resolveSpawnModel(Y):Y;if(Y&&!H)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Y}`);let z=J?(G)=>J.spawnEnv(G,H):void 0;if($.provider==="dsh"){if(!J||!H||!q0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new K6({...$,model:H,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(P6(),!D0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new a3({workDir:$.workDir,model:H,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&&!Z$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let W=new k2({workDir:$.workDir,model:H,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z,...J?.codexApiProvider?{apiProvider:J.codexApiProvider}:{}});if(!J?.codexApiProvider)$1(W,Z);return{process:W,sourceRevision:V}}var v6=O(()=>{G0();iV();f2();J1();e();f0();MX()});function Y8($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function AX($){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 v1($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function f6($){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 VF($){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 XF($){let Z=v1($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${f6($.file.url)})`:Z,Q=$.status==="failed"?`<font color='red'>${v1($.error??"交付失败")}</font>`:`<font color='grey'>${AX($.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:VF($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
112
+ ${Q}`}]}]}}function h6($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Q=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Y=$.folderAccessReady&&$.folder?f6($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],X=V.slice(0,YF),H=V.slice(X.length).filter((z)=>z.status==="failed").length;return{schema:"2.0",config:{update_multi:!0,width_mode:"default",summary:{content:`交付文件 · ${Q}`}},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:`**本次交付 · ${Q}**`},{tag:"column_set",element_id:E.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(XF),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${H?`中有 ${H} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${v1($.error)}</font>`}]:[],...Y?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:Y}]},{tag:"markdown",content:"<font color='grey'>卡片仅列本轮文件;管理入口查看本群全部云空间交付文件,可重命名、移动或删除。</font>",text_size:"notation"}]:[]]}}}function I6($){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
+ 工作目录:${v1($.workDir)}
114
+ 群:${v1($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:v1($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${v1($.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?.enabled&&!$.settings.folder?[{tag:"markdown",content:"本群首次交付时创建独立云空间文件夹。"}]:[],...$.settings?.folder?[{tag:"button",text:{tag:"plain_text",content:"管理群文件"},type:"primary_filled",width:"fill",behaviors:[{type:"open_url",default_url:f6($.settings.folder.url)}]}]:[]]}}}var YF=12;var V8=O(()=>{C0()});function X8($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function H8($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function HF($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Q=Z-J,Y=Math.max(0,$-J),V=Math.max(0,Q-Y);return Math.round(Math.min(100,Math.max(0,V/Q*100)))}function NX($,Z,J){let Q=HF($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function OX($){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 z8($,Z){let J=OX($);return Z!=null&&Z>0?`${J}/${OX(Z)}`:`${J}/--`}function RX($,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 m6($,Z,J){let Q=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Q||"MISS"}/${J||"MISS"}`}function G8($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function zF($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function WF($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function W8($){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 TX($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function xX($){let Z=$.filter((V)=>V.status==="completed").length,J=$.filter((V)=>V.status==="inProgress").length,Q=$.filter((V)=>V.status==="pending").length,Y=[`${$.length} 项`];if(J)Y.push(`${J} 进行中`);if(Z)Y.push(`${Z} 完成`);if(Q)Y.push(`${Q} 待办`);return Y.join(" · ")}function GF($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${xX($)}`}function g6($){return typeof $==="number"&&Number.isFinite($)?$:null}function KF($){let Z=g6($.startedAtMs),J=g6($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${U0((J-Z)/1000)}`}function BF($){let Z=g6($);return Z==null?null:W8(Z)}function _F($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=BF($.preTokens),V=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Q)J.push(`**触发**: ${Q}`);if(Y)J.push(`**压缩前**: ${Y} tokens`);if(V)J.push(`**来源**: ${V}`);return J.length>0?J:["压缩完成,无摘要内容"]}function p6($,Z,J){if($==null||!Number.isFinite($))return null;let Q=NX($,Z,J);return Q?`${Q.used}% · ${z8($,Z)}`:"--"}function c6($){let Z=W8($?.input_tokens??Number.NaN),J=W8($?.cache_read_input_tokens??Number.NaN),Q=W8($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function z9($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",V=Y?"✅":"⏳",X=Y?KF(Q):"",H=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,z=_F(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
115
+ `)}]}}function SX($,Z,J=""){let Q=["**\uD83D\uDCCB 当前计划**"],Y=Z?.trim();if(Y)Q.push(""),Q.push(Y);if($.length>0){Q.push("");for(let V of $)Q.push(`- ${zF(V.status)} ${V.step}`)}else{let V=J.trim();if(Q.push(""),V)Q.push("正在生成计划草稿..."),Q.push(""),Q.push(V);else Q.push("--")}return Q.join(`
116
+ `)}function u6($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:GF($,J)}},expanded:!1,elements:[{tag:"markdown",content:SX($,Z,J)}]}}function W9($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${xX($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:SX($,Z)}]}}function l6($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${TX($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${U0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${TX($.status)}: ${WF($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
117
+ `)}]}}function K8($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Q=$.userInputs??[],Y=`\uD83D\uDCE5 收到 (${Q.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,V=Q.length>0?[{tag:"collapsible_panel",element_id:E.userInput,header:{title:{tag:"plain_text",content:Y}},expanded:!1,elements:Q.map((X)=>({tag:"markdown",content:Z0(X)}))}]:[];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:E.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function CX($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function jF($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function LF($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let V=$.options[Y],X=V.description?` · ${Z0(V.description)}`:"";Q.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:Y}}],elements:[{tag:"markdown",content:`**${Z0(V.label)}**${X}`}]})}return Q}function EX($,Z,J,Q){if($.length===0)return null;let Y=$.length,V=[];for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let z=CX(H,X,Y),W=Q.get(X);if(W){let G=jF(H,W),K=[`**✅ ${z}**`,`**回答**:${G}`];V.push({tag:"markdown",content:K.join(`
118
+ `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),H.options.length>0)V.push(...LF(H,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function u2($,Z,J,Q="\uD83E\uDD14",Y){let V=J.length,X=Y?.answered??new Map,H=Y?.currentIdx,z=H===void 0&&X.size>0,W=[],G;if(Y?.waitingFor)G=Y.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",W.push({tag:"markdown",content:Y.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){G=`${Q} 已回答 · ${V}/${V}`,W.push(...EX(J,Z,H,X)??[]);let K=[...X.values()].reverse().find((_)=>_.user)?.user;if(K)W.push({tag:"markdown",content:`
119
+ *— 由 ${K} 回答*`})}else if(H!==void 0&&J[H])G=`${Q} 等你确认 · ${H+1}/${V}`,W.push(...EX(J,Z,H,X)??[]);else if(G=`${Q} 等你确认`,J[0])W.push({tag:"markdown",content:`**${CX(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!z&&!Y?.waitingFor,elements:W}}var bX=O(()=>{C0()});import{isAbsolute as d6,relative as qF}from"node:path";function _8($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function j8($){return $==="write_stdin"||$.endsWith(".write_stdin")}function PF($){return _8($)||j8($)}function L8($){return $==="FileChange"||$==="fileChange"}function K9($){return $==="WebSearch"||$==="webSearch"}function q8($){return $==="WebFetch"||$==="webFetch"}function t6($){return $==="MCP"}function B9($){return $==="ImageGeneration"||$==="imageGeneration"}function r6($){return $==="Agent"||$==="Task"}function F8($){return $==="Read"}function P8($){return $==="Write"}function D8($){return $==="Edit"||$==="NotebookEdit"}function U8($){return $==="MultiEdit"}function e6($){return $==="Glob"||$==="Grep"||$==="LS"}function M8($){return $==="TodoWrite"}function A8($){return $==="ExitPlanMode"}function O8($){return $.startsWith(wX)}function yX($){return O8($)?$.slice(wX.length):$}function f1($){if(O8($))return"服务端工具";if(L8($))return"文件变更";if(K9($))return"网页搜索";if(q8($))return"网页读取";if(B9($))return"图片生成";if(F8($))return"读取文件";if(P8($))return"写入文件";if(D8($)||U8($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(M8($))return"更新待办";if(A8($))return"确认计划";if($==="Task")return"子任务";return PF($)?"Bash":$}function z1($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(O8($))return J(DF($,Z),80);if(!Z||typeof Z!=="object")return"";if(_8($))return UF(Z);if(j8($))return MF(Z);if(L8($))return J(NF(Z),80);if(K9($))return J(tX(Z),80);if(q8($))return J(bF(Z),80);if(t6($))return J(wF(Z),80);if(B9($))return J(vF(Z),80);if(r6($))return J(fF(Z),80);if(F8($))return J(RF(Z),80);if(P8($))return J(TF(Z),80);if(D8($))return J(EF(Z),80);if(U8($))return J(xF(Z),80);if(e6($))return J(SF($,Z),80);if(M8($))return J(CF(Z),80);if(A8($))return J(_9(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Q of Object.values(Z))if(typeof Q==="string"&&Q)return J(Q,80);return""}function DF($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:yX($),Q=_9(Z?.input);return Q?`${J}: ${Q}`:J}function UF($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=fX($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Q=J.command;if(!Q)return"";let Y=Q.split(/\r?\n/).map((V)=>V.trim()).filter(Boolean);if(Y.length<=1)return Z(Q.replace(/\s+/g," "),80);return`Shell 脚本 · ${Y.length} 行 · ${Z(x2(Q),46)}`}function vX($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function MF($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${vX($)}${J}`}function fX($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=c7(Z);return{description:Q.description||J,command:Q.command}}function a0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
120
120
  ${$}
121
- ${J}`}function w$($,Z=sP,J=""){if($.length<=Z)return c0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,c0(`${Y}
121
+ ${J}`}function p$($,Z=FF,J=""){if($.length<=Z)return a0($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,a0(`${Q}
122
122
  ... output 已截断 ...`,J)].join(`
123
- `)}function p($){return"`"+String($??"").replace(/`/g,"'")+"`"}function J$($,Z=3000){return c0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function X9($){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 NX($,Z,J){let Y=OX($),Q=Y.command,V=Y.description,X=[];if(V)X.push(`**目的**: ${V}`);let H=$?.cwd??$?.workdir;if(H)X.push(`**cwd**: ${p(H)}`);if($?.source)X.push(`**source**: ${p($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(c0(Q||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(w$(Z));return X.join(`
124
- `)}function RX($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${AX($)}`),Q!==void 0)Y.push(`**session**: ${p(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(c0(V))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(w$(Z));return Y.join(`
125
- `)}function TX($){return Array.isArray($?.changes)?$.changes:[]}function EX($){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&&f6(J)&&f6(Z)){let Y=oP(Z,J);if(Y&&!Y.startsWith("..")&&!f6(Y))return Y}return J}function Zq($){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 xX($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function I6($){let Z=Zq($);if(xX($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function g6($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function m6($){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 SX($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function p6($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function Jq($){return $.length>1800?$.slice(0,1800)+`
126
- ... diff 已截断 ...`:$}function Yq($){let Z=TX($),J=EX($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?Y9($.grantRoot):"";if(z&&G)return`${z} · ${G}`;return z||(G?`申请修改 ${G}`:"")}let Y=Z.map((z)=>m6(g6(z))).reduce(SX,{added:0,removed:0}),Q=p6(Y),V=[...new Set(Z.map(I6))],X=Y9(Z[0]?.path,J),H=Q?` · ${Q}`:"";if(Z.length===1)return`${V[0]} ${X}${H}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${H}`}function CX($,Z,J){let Y=TX($),Q=EX($),V=[];if(Y.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)V.push(`**原因**: ${G}`);if($?.grantRoot)V.push(`**范围**: ${p(Y9($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(c0(Z.slice(0,3000)));return V.length>0?V.join(`
127
- `):c0(JSON.stringify($??{},null,2).slice(0,2000))}let X=Y.map((G)=>m6(g6(G))).reduce(SX,{added:0,removed:0}),H=p6(X);if(V.push(`**文件**: ${Y.length} 个`),H)V.push(`**行数**: ${H}`);if($?.status)V.push(`**状态**: ${p($.status)}`);let z=Y.slice(0,5);for(let G of z){let W=g6(G),K=p6(m6(W)),_=Y9(G?.path,Q),L=K?`**${I6(G)}** ${p(_)} · ${K}`:`**${I6(G)}** ${p(_)}`;V.push(""),V.push(L);let j=xX(G);if(j)V.push(`来自 ${p(Y9(j,Q))}`);V.push(W?c0(Jq(W),"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(`
128
- `)}function $1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function Qq($){let Z=$1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function Vq($){let Z=$1($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function Xq($){let Z=$1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function Hq($){let Z=$1($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function zq($,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 bX($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function Gq($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let V=bX(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 Wq($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function g2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(w$(Z,1200))}function kX($,Z,J){let Y=[],Q=$1($);if(Q)Y.push(`**路径**: ${p(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${p($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${p($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
129
- `):J$($??{},2000)}function yX($,Z,J){let Y=[],Q=$1($),V=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${p(Q)}`);if(V){let X=V.split(/\r?\n/).length;Y.push(`**内容**: ${X} 行 / ${V.length} 字符`),Y.push(w$(V,1200))}if(J)Y.push(""),Y.push(J);return g2(Y,Z),Y.length>0?Y.join(`
130
- `):J$($??{},2000)}function wX($,Z,J){let Y=[],Q=$1($);if(Q)Y.push(`**路径**: ${p(Q)}`);if($?.cell_id)Y.push(`**cell**: ${p($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${p($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(w$($.old_string,800));let V=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(V)Y.push(""),Y.push("**替换为**"),Y.push(w$(V,800));if(J)Y.push(""),Y.push(J);return g2(Y,Z),Y.length>0?Y.join(`
131
- `):J$($??{},2000)}function vX($,Z,J){let Y=[],Q=$1($),V=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${p(Q)}`);Y.push(`**编辑**: ${V.length} 处`);for(let[X,H]of V.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${X+1}${H?.replace_all?" · 全局替换":""}**`),typeof H?.old_string==="string")Y.push("查找:"),Y.push(w$(H.old_string,500));if(typeof H?.new_string==="string")Y.push("替换为:"),Y.push(w$(H.new_string,500))}if(V.length>5)Y.push(""),Y.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return g2(Y,Z),Y.join(`
132
- `)}function fX($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${p(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${p(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${p(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${p(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${p(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${p(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${p(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${p(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(p).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return g2(Q,J),Q.join(`
133
- `)}function hX($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let V of Y.slice(0,12)){let X=bX(V?.status),H=String(V?.content??V?.activeForm??"").trim()||"(空)";Q.push(`- ${X}: ${H}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return g2(Q,Z),Q.join(`
134
- `)}function d6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function i6($,Z){return d6(Z)??$?.action??{}}function n6($,Z){let J=i6($,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 a6($,Z){let J=i6($,Z);return String(J?.url??$?.url??"")}function IX($){let Z=n6($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=a6($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function Kq($,Z){let J=n6($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=a6($,Z);if(Y)return Y;return IX($)}function gX($,Z,J){let Y=i6($,Z),Q=n6($,Z),V=a6($,Z),X=[],H=typeof Y?.type==="string"?Y.type:"";if(H==="search"||Q.length>0){if(X.push("**动作**: 搜索"),Q.length>0){X.push(""),X.push("**查询**");for(let z of Q.slice(0,6))X.push(`- ${p(z)}`);if(Q.length>6)X.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(H==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${p(V)}`)}else if(H==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${p(V)}`);if(Y?.pattern)X.push(`**关键词**: ${p(Y.pattern)}`)}else if(X.push(`**动作**: ${H?p(H):"网页搜索"}`),V)X.push(`**URL**: ${p(V)}`);if(J)X.push(""),X.push(J);if(X.length===1&&!Q.length&&!V&&Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(c0(Z.slice(0,3000),"json"));return X.join(`
135
- `)}function mX($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${p($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return g2(Y,Z),Y.join(`
136
- `)}function Bq($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=X9($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function pX($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${p($.server)}`);if($?.tool)Y.push(`**tool**: ${p($.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(J$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let V=d6(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((H)=>typeof H?.text==="string"?H.text:"").filter(Boolean);if(X.length>0)Y.push(X.join(`
137
- `).slice(0,3000));if(V.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(J$(V.structuredContent,2000));if(X.length===0&&!V.structuredContent)Y.push(J$(V,3000))}else Y.push(V?J$(V,3000):c0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
138
- `):J$($??{},2000)}function _q($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${p(typeof Z?.tool==="string"&&Z.tool?Z.tool:UX($))}`],V=Z?.input;if(V&&typeof V==="object")if(Q.push(""),Q.push("**input**"),Object.keys(V).length>0)Q.push(J$(V,2000));else Q.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Q.push(`**input**: ${p(V)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(w$(J,3000));return Q.join(`
139
- `)}function jq($){return typeof $?.status==="string"?$.status:""}function cX($,Z,J,Y){let Q=[];if($?.status)Q.push(`**状态**: ${p($.status)}`);if($?.prompt)Q.push("","**提示词**",c0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Q.push("",$.prompt?"**实际提示词**":"**提示词**",c0(String($.revisedPrompt)))}if(J)Q.push(""),Q.push(J);if(!Y&&Z!=null&&Z.trim())Q.push(""),Q.push("---"),Q.push("**输出**"),Q.push(p(Z.trim()));return Q.length>0?Q.join(`
140
- `):J$($??{},2000)}function Lq($){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 Y8($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${p($.tool)}`);if($?.model)Y.push(`**model**: ${p($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${p($.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=d6(Z);Y.push(Q?J$(Q,3000):c0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
141
- `):J$($??{},2000)}function O$($,Z,J,Y,Q="⏳",V,X){let H=Q9(Z)&&Y!=null?Kq(J,Y):e$(Z,J),z=H.length>80?H.slice(0,80)+"…":H,G=S1(Z),W=z?`${Q} \uD83D\uDD27 ${G}: ${z}`:`${Q} \uD83D\uDD27 ${G}`,K=V?`
142
-
143
- ${V}`:"",_=Q8(Z)?NX(J,Y,V):V8(Z)?RX(J,Y,V):j8(Z)?_q(Z,J,Y,V):X8(Z)?CX(J,Y,V):Q9(Z)?gX(J,Y,V):H8(Z)?mX(J,Y,V):c6(Z)?pX(J,Y,V):V9(Z)?cX(J,Y,V,X):z8(Z)?kX(J,Y,V):G8(Z)?yX(J,Y,V):W8(Z)?wX(J,Y,V):K8(Z)?vX(J,Y,V):l6(Z)?fX(Z,J,Y,V):B8(Z)?hX(J,Y,V):_8(Z)?Y8({prompt:X9(J)||"提交计划"},Y,V):u6(Z)?Y8(J,Y,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Y!=null?`
123
+ `)}function c($){return"`"+String($??"").replace(/`/g,"'")+"`"}function V$($,Z=3000){return a0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function _9($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Q=Z[J];if(typeof Q==="string"&&Q.length>0)return Q}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function hX($,Z,J){let Q=fX($),Y=Q.command,V=Q.description,X=[];if(V)X.push(`**目的**: ${V}`);let H=$?.cwd??$?.workdir;if(H)X.push(`**cwd**: ${c(H)}`);if($?.source)X.push(`**source**: ${c($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(a0(Y||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(p$(Z));return X.join(`
124
+ `)}function IX($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${vX($)}`),Y!==void 0)Q.push(`**session**: ${c(Y)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Q.push(""),Q.push("**输入**"),Q.push(a0(V))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(p$(Z));return Q.join(`
125
+ `)}function gX($){return Array.isArray($?.changes)?$.changes:[]}function mX($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function G9($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&d6(J)&&d6(Z)){let Q=qF(Z,J);if(Q&&!Q.startsWith("..")&&!d6(Q))return Q}return J}function AF($){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 pX($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function n6($){let Z=AF($);if(pX($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function a6($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function o6($){let Z=0,J=0;for(let Q of $.split(/\r?\n/)){if(Q.startsWith("+++")||Q.startsWith("---"))continue;if(Q.startsWith("+"))Z++;if(Q.startsWith("-"))J++}return{added:Z,removed:J}}function cX($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function s6($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function OF($){return $.length>1800?$.slice(0,1800)+`
126
+ ... diff 已截断 ...`:$}function NF($){let Z=gX($),J=mX($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",W=$?.grantRoot?G9($.grantRoot):"";if(z&&W)return`${z} · ${W}`;return z||(W?`申请修改 ${W}`:"")}let Q=Z.map((z)=>o6(a6(z))).reduce(cX,{added:0,removed:0}),Y=s6(Q),V=[...new Set(Z.map(n6))],X=G9(Z[0]?.path,J),H=Y?` · ${Y}`:"";if(Z.length===1)return`${V[0]} ${X}${H}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${H}`}function uX($,Z,J){let Q=gX($),Y=mX($),V=[];if(Q.length===0){let W=typeof $?.reason==="string"?$.reason.trim():"";if(W)V.push(`**原因**: ${W}`);if($?.grantRoot)V.push(`**范围**: ${c(G9($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(a0(Z.slice(0,3000)));return V.length>0?V.join(`
127
+ `):a0(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((W)=>o6(a6(W))).reduce(cX,{added:0,removed:0}),H=s6(X);if(V.push(`**文件**: ${Q.length} 个`),H)V.push(`**行数**: ${H}`);if($?.status)V.push(`**状态**: ${c($.status)}`);let z=Q.slice(0,5);for(let W of z){let G=a6(W),K=s6(o6(G)),_=G9(W?.path,Y),L=K?`**${n6(W)}** ${c(_)} · ${K}`:`**${n6(W)}** ${c(_)}`;V.push(""),V.push(L);let j=pX(W);if(j)V.push(`来自 ${c(G9(j,Y))}`);V.push(G?a0(OF(G),"diff"):"_无 diff 内容_")}if(Q.length>z.length)V.push(""),V.push(`还有 ${Q.length-z.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
128
+ `)}function W1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function RF($){let Z=W1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function TF($){let Z=W1($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function EF($){let Z=W1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function xF($){let Z=W1($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function SF($,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 lX($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function CF($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let V=lX(Y?.status);J.set(V,(J.get(V)??0)+1)}let Q=[...J.entries()].map(([Y,V])=>`${Y} ${V}`).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function bF($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function l2($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(p$(Z,1200))}function dX($,Z,J){let Q=[],Y=W1($);if(Y)Q.push(`**路径**: ${c(Y)}`);if($?.offset!=null)Q.push(`**offset**: ${c($.offset)}`);if($?.limit!=null)Q.push(`**limit**: ${c($.limit)}`);if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("_内容已读取,未展开到群聊卡片。_");return Q.length>0?Q.join(`
129
+ `):V$($??{},2000)}function iX($,Z,J){let Q=[],Y=W1($),V=typeof $?.content==="string"?$.content:"";if(Y)Q.push(`**路径**: ${c(Y)}`);if(V){let X=V.split(/\r?\n/).length;Q.push(`**内容**: ${X} 行 / ${V.length} 字符`),Q.push(p$(V,1200))}if(J)Q.push(""),Q.push(J);return l2(Q,Z),Q.length>0?Q.join(`
130
+ `):V$($??{},2000)}function nX($,Z,J){let Q=[],Y=W1($);if(Y)Q.push(`**路径**: ${c(Y)}`);if($?.cell_id)Q.push(`**cell**: ${c($.cell_id)}`);if($?.edit_mode)Q.push(`**模式**: ${c($.edit_mode)}`);if($?.replace_all)Q.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Q.push(""),Q.push("**查找**"),Q.push(p$($.old_string,800));let V=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(V)Q.push(""),Q.push("**替换为**"),Q.push(p$(V,800));if(J)Q.push(""),Q.push(J);return l2(Q,Z),Q.length>0?Q.join(`
131
+ `):V$($??{},2000)}function aX($,Z,J){let Q=[],Y=W1($),V=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${c(Y)}`);Q.push(`**编辑**: ${V.length} 处`);for(let[X,H]of V.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${X+1}${H?.replace_all?" · 全局替换":""}**`),typeof H?.old_string==="string")Q.push("查找:"),Q.push(p$(H.old_string,500));if(typeof H?.new_string==="string")Q.push("替换为:"),Q.push(p$(H.new_string,500))}if(V.length>5)Q.push(""),Q.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return l2(Q,Z),Q.join(`
132
+ `)}function oX($,Z,J,Q){let Y=[];if($==="Glob"){if(Y.push("**动作**: 匹配文件"),Z?.pattern)Y.push(`**pattern**: ${c(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${c(Z.path)}`)}else if($==="Grep"){if(Y.push("**动作**: 搜索文件"),Z?.pattern)Y.push(`**pattern**: ${c(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${c(Z.path)}`);if(Z?.glob)Y.push(`**glob**: ${c(Z.glob)}`);if(Z?.type)Y.push(`**type**: ${c(Z.type)}`);if(Z?.output_mode)Y.push(`**output**: ${c(Z.output_mode)}`)}else{if(Y.push("**动作**: 列目录"),Z?.path)Y.push(`**path**: ${c(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Y.push(`**ignore**: ${Z.ignore.map(c).join(" ")}`)}if(Q)Y.push(""),Y.push(Q);return l2(Y,J),Y.join(`
133
+ `)}function sX($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let V of Q.slice(0,12)){let X=lX(V?.status),H=String(V?.content??V?.activeForm??"").trim()||"(空)";Y.push(`- ${X}: ${H}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return l2(Y,Z),Y.join(`
134
+ `)}function $Z($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function ZZ($,Z){return $Z(Z)??$?.action??{}}function JZ($,Z){let J=ZZ($,Z),Q=Array.isArray(J?.queries)?J.queries.filter((V)=>typeof V==="string"&&V.length>0):[],Y=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Q.length>0?Q:Y?[Y]:[]}function QZ($,Z){let J=ZZ($,Z);return String(J?.url??$?.url??"")}function tX($){let Z=JZ($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=QZ($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function kF($,Z){let J=JZ($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=QZ($,Z);if(Q)return Q;return tX($)}function rX($,Z,J){let Q=ZZ($,Z),Y=JZ($,Z),V=QZ($,Z),X=[],H=typeof Q?.type==="string"?Q.type:"";if(H==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let z of Y.slice(0,6))X.push(`- ${c(z)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(H==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${c(V)}`)}else if(H==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${c(V)}`);if(Q?.pattern)X.push(`**关键词**: ${c(Q.pattern)}`)}else if(X.push(`**动作**: ${H?c(H):"网页搜索"}`),V)X.push(`**URL**: ${c(V)}`);if(J)X.push(""),X.push(J);if(X.length===1&&!Y.length&&!V&&Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(a0(Z.slice(0,3000),"json"));return X.join(`
135
+ `)}function eX($,Z,J){let Q=["**动作**: 读取网页"];if($?.url)Q.push(`**URL**: ${c($.url)}`);if($?.prompt)Q.push(""),Q.push("**问题**"),Q.push(String($.prompt).slice(0,1200));if(J)Q.push(""),Q.push(J);return l2(Q,Z),Q.join(`
136
+ `)}function wF($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=_9($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function $H($,Z,J){let Q=[];if($?.server)Q.push(`**server**: ${c($.server)}`);if($?.tool)Q.push(`**tool**: ${c($.tool)}`);let Y=$?.arguments;if(Y&&typeof Y==="object"&&Object.keys(Y).length>0){if(Q.length>0)Q.push("");Q.push("**arguments**"),Q.push(V$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let V=$Z(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((H)=>typeof H?.text==="string"?H.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
137
+ `).slice(0,3000));if(V.structuredContent)Q.push(""),Q.push("**structuredContent**"),Q.push(V$(V.structuredContent,2000));if(X.length===0&&!V.structuredContent)Q.push(V$(V,3000))}else Q.push(V?V$(V,3000):a0(Z.slice(0,3000)))}return Q.length>0?Q.join(`
138
+ `):V$($??{},2000)}function yF($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${c(typeof Z?.tool==="string"&&Z.tool?Z.tool:yX($))}`],V=Z?.input;if(V&&typeof V==="object")if(Y.push(""),Y.push("**input**"),Object.keys(V).length>0)Y.push(V$(V,2000));else Y.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Y.push(`**input**: ${c(V)}`);if(Q)Y.push(""),Y.push(Q);if(J!=null)Y.push(""),Y.push("---"),Y.push("**结果**"),Y.push(p$(J,3000));return Y.join(`
139
+ `)}function vF($){return typeof $?.status==="string"?$.status:""}function ZH($,Z,J,Q){let Y=[];if($?.status)Y.push(`**状态**: ${c($.status)}`);if($?.prompt)Y.push("","**提示词**",a0(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Y.push("",$.prompt?"**实际提示词**":"**提示词**",a0(String($.revisedPrompt)))}if(J)Y.push(""),Y.push(J);if(!Q&&Z!=null&&Z.trim())Y.push(""),Y.push("---"),Y.push("**输出**"),Y.push(c(Z.trim()));return Y.length>0?Y.join(`
140
+ `):V$($??{},2000)}function fF($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Q=typeof $?.description==="string"?$.description:"",Y=typeof $?.subject==="string"?$.subject:"",V=Q||Y||J;return Z&&V?`${Z}: ${V}`:V||Z}function B8($,Z,J){let Q=[];if($?.tool)Q.push(`**tool**: ${c($.tool)}`);if($?.model)Q.push(`**model**: ${c($.model)}`);if($?.description)Q.push(`**描述**: ${$.description}`);if($?.subagent_type)Q.push(`**类型**: ${c($.subagent_type)}`);if($?.prompt){if(Q.length>0)Q.push("");Q.push("**prompt**"),Q.push(String($.prompt).slice(0,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){Q.push(""),Q.push("---"),Q.push("**状态**");let Y=$Z(Z);Q.push(Y?V$(Y,3000):a0(Z.slice(0,3000)))}return Q.length>0?Q.join(`
141
+ `):V$($??{},2000)}function E$($,Z,J,Q,Y="⏳",V,X){let H=K9(Z)&&Q!=null?kF(J,Q):z1(Z,J),z=H.length>80?H.slice(0,80)+"…":H,W=f1(Z),G=z?`${Y} \uD83D\uDD27 ${W}: ${z}`:`${Y} \uD83D\uDD27 ${W}`,K=V?`
142
+
143
+ ${V}`:"",_=_8(Z)?hX(J,Q,V):j8(Z)?IX(J,Q,V):O8(Z)?yF(Z,J,Q,V):L8(Z)?uX(J,Q,V):K9(Z)?rX(J,Q,V):q8(Z)?eX(J,Q,V):t6(Z)?$H(J,Q,V):B9(Z)?ZH(J,Q,V,X):F8(Z)?dX(J,Q,V):P8(Z)?iX(J,Q,V):D8(Z)?nX(J,Q,V):U8(Z)?aX(J,Q,V):e6(Z)?oX(Z,J,Q,V):M8(Z)?sX(J,Q,V):A8(Z)?B8({prompt:_9(J)||"提交计划"},Q,V):r6(Z)?B8(J,Q,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
144
144
  ---
145
145
  **output:**
146
146
  \`\`\`
147
- `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!1,elements:[{tag:"markdown",content:$0(_)},...V9(Z)&&X?[{tag:"img",img_key:X,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function H9($,Z){let J=Z.length,Y=Z.some((z)=>z.isError),Q=Z.every((z)=>z.output!==null),V=Y?"❌":Q?"✅":"⏳",X=J===1?(()=>{let z=DX(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,H=Z.map((z)=>{let G=DX(z);return G?`\`${G}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:$0(H.join(`
148
- `))}]}}function DX($){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?"✅":"⏳",X=J===1?(()=>{let z=e$("Read",Z[0]?.input);return z?`${V} \uD83D\uDD27 Read: ${z}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,H=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:$0(H.join(`
149
- `))}]}}function o6($,Z,J,Y){let Q=e$(Z,J),V=S1(Z),X=Q?`\uD83D\uDD10 等审批 · ${V}: ${Q}`:`\uD83D\uDD10 等审批 · ${V}`,H=Q8(Z)?NX(J,null):V8(Z)?RX(J,null):X8(Z)?CX(J,null):Q9(Z)?gX(J,null):H8(Z)?mX(J,null):c6(Z)?pX(J,null):V9(Z)?cX(J,null):z8(Z)?kX(J,null):G8(Z)?yX(J,null):W8(Z)?wX(J,null):K8(Z)?vX(J,null):l6(Z)?fX(Z,J,null):B8(Z)?hX(J,null):_8(Z)?Y8({prompt:X9(J)||"提交计划"},null):u6(Z)?Y8(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!0,elements:[{tag:"markdown",content:H},{tag:"column_set",columns:[h6("✅ 允许","primary",Y,"allow"),h6("♾️ 始终允许","default",Y,"allow_always"),h6("❌ 拒绝","danger",Y,"deny")]}]}}function h6($,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 sP=300,MX="server_tool:";var uX=O(()=>{C0();A3()});import{execFile as Pq}from"node:child_process";import{readFileSync as s6,statfsSync as qq,statSync as lX}from"node:fs";import{cpus as Fq,homedir as Dq}from"node:os";import{promisify as Mq}from"node:util";function Aq(){try{let $=s6("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:Fq().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return B(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function Oq(){try{let $=s6("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));return X?parseInt(X[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 B(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function dX($,Z){try{let J=qq(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 B(`sysinfo: statfs ${Z} failed: ${J}`),null}}function Nq(){let $=[],Z=dX("/","/");if(Z)$.push(Z);let J=Dq();if(J&&J!=="/"){let Y=!1;try{let Q=lX("/"),V=lX(J);Y=Q.dev===V.dev}catch{}if(!Y){let Q=dX("$HOME",J);if(Q)$.push(Q)}}return $}function Rq(){try{let $=s6("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function iX($,Z=2000){try{let{stdout:J}=await Uq("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function nX($){return aX.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function Tq(){let $=await iX(["list-units","--type=service","--all","--no-legend","--plain",...aX.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
150
- `).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 W=z.replace(/^●\s*/,"").split(/\s+/)[0];if(!W)continue;if(!nX(W))continue;J.push(W)}if(J.length===0)return{services:[],error:null};let Y=await iX(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=Rq(),V=Y.split(/\n\s*\n/),X=[],H=(z)=>{let G=parseInt(z??"0",10);if(G<=0||Q===null)return null;return Math.max(0,Q-G/1e6)};for(let z of V){let G={};for(let K of z.split(`
151
- `)){let _=K.indexOf("=");if(_<=0)continue;G[K.slice(0,_)]=K.slice(_+1)}let W=G.Id??"";if(!nX(W))continue;X.push({name:W.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:H(G.ActiveEnterTimestampMonotonic),stateAgoSec:H(G.StateChangeTimestampMonotonic)})}return X.sort((z,G)=>z.name.localeCompare(G.name)),{services:X,error:null}}async function oX(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=Aq(),Z=Oq(),J=Nq(),{services:Y,error:Q}=await Tq();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var Uq,aX,G9="cc-* / codex-*";var t6=O(()=>{f();Uq=Mq(Pq),aX=["cc-","codex-"]});function Z1($){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 r6($,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),X=Q>=100?"red":Q>=80?"orange":"green",H=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${Z1($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Q)}%${Y}**
152
- <font color='${X}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${H}</font>`,text_size:"notation"}]}function L8($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function Eq($){if($===null||!Number.isFinite($)||$<0||$>100)return"MISS";let Z=`${Math.round($)}%`;return $>=100?`<font color='red'>${Z}</font>`:$>=80?`<font color='orange'>${Z}</font>`:Z}function xq($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Y=`${L8(J)} ${Eq($.percent)}`;if($.kind==="monthly")return Y;if($.unreportedFull)return`${Y}(满窗)`;return`${Y}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?Z1($.resetsAt):"MISS"}`}function sX($){if(!$)return"加载中…";if($.state==="not_applicable")return"—";if($.state!=="ok"){let Y=$.state==="no_credentials"?"未登录或未配置":$.state==="rate_limited"?"API 限频":($.reason??"查询失败").replace(/^Claude 原生额度接口未返回 rate_limits 数据$/,"原生接口未返回额度");return`<font color='red'>MISS · ${L8(Y.slice(0,100))}</font>`}let Z=(Y,Q)=>{if(!Number.isFinite(Y))return"MISS";return`${Q==="USD"?"$":Q==="CNY"?"¥":L8(Q)} ${Y.toFixed(2)}`};if($.kind==="balance")return`余额 ${$.balance?Z($.balance.remaining,$.balance.currency):"MISS"}`;if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${Z($.quota.remaining,$.quota.currency)} / ${Z($.quota.limit,$.quota.currency)}`;let J=$.windows.map(xq);if(!J.length)J.push("额度 MISS");if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function tX($){return{tag:"markdown",text_size:"notation",content:`**${L8($.label)}** ${sX($.usage)}`}}var rX=()=>{};function K9($,Z){return Z}function e6($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:T.footer,content:K9($.title,$.status)}]}}}function eX($){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 Sq($){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 W9($){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 yq($){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 wq($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${G9} _n/a_`].join(`
153
- `);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}% (${eX($.mem.usedBytes)}/${eX($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${G9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${G9} _无_`);else{Z.push(`**服务** ${G9} (${$.services.length})`);for(let J of $.services){let Y=kq[J.active]??"·",Q=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${W9(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)X.push(`上次活跃 ${W9(Q*1000)}前`);else X.push("从未启动");if(V!=null){let H=J.active==="failed"?"已挂":"已停";X.push(`${H} ${W9(V*1000)}`)}}else if(V!=null)X.push(`已 ${W9(V*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
154
- `)}function vq($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=Cq[J.status]??"·",Q=bq[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${W9(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",H=J.codexAccountName===void 0?"":` · Codex:${J1(Y$(J.codexAccountName))}`;return` · ${Y} \`${J.name}\` · ${Q}${V}${X}${H}`}).join(`
155
- `)}function P8($,Z=T.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:vq($)}]}}function fq($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${VZ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
156
- `)}function q8($,Z=T.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:fq($)}}function F8($,Z=T.consoleHost){let J=yq($);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:wq($)}]}}function $Z($){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(hq).join(" · ")}`}function hq($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function B9($){let Z=$.accountUsages;return{tag:"collapsible_panel",element_id:T.consoleUsage,expanded:!0,header:{title:{tag:"plain_text",content:"全部账号额度 · 已用 / 距重置"},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"2px",elements:Z===void 0?[{tag:"markdown",text_size:"notation",content:"加载中…"}]:Z.length?Z.map(tX):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function $H($,Z){return[q8($,Z),P8($),F8($.sysinfo),B9($)]}function D8($){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:$H($)}}}function ZZ($){return C1($.sessionName,{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${J1($.currentDisplay??"未选择")}
157
- 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Y)=>(Y.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:T.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)=>Iq(Y,$.panelId))}]:[]})]})}function Iq($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${Y$($.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:`**${Y$($.display)}**
158
- ${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 JZ($){return C1($.sessionName,ZH($))}function YZ($){return C1($.sessionName,A8($))}function _9($){return C1($.sessionName,O8($),"green")}function j9($,Z){return{tag:"collapsible_panel",element_id:T.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:Y$(Z)}]}}function M8($,Z,J){return C1($,j9(Z,J),Z?"orange":"red")}function C1($,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 ZH($){let Z=pq($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${JH($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
159
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?gq($.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 gq($,Z){let{sourceId:J,page:Y,totalPages:Q}=Z,V=(X,H)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:X},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:H}}]}]});return[{tag:"markdown",content:`第 ${Y+1} / ${Q} 页`},{tag:"column_set",columns:[...Y>0?[V("上一页",Y-1)]:[],...Y+1<Q?[V("下一页",Y+1)]:[]]}]}function U8($,Z="cancelled"){return C1($,{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function QZ($,Z,J){return C1($,{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
160
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function L9($,Z,J){return{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
161
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function A8($){return{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${lq($.model)}`,`当前: ${JH($.currentModel,$.currentEffort)}`].join(`
162
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>cq($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function O8($){return{tag:"collapsible_panel",element_id:T.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",J1(YH($.model,$.effort,$.provider)),Y$($.scope)].join(`
163
- `)}]}}function mq($,Z,J,Y=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${Y$($.displayName)}** · 未配置
164
- ${Y$($.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?`**${Y$($.displayName)}**`:`**${J1($.model)}**`,V=[$.isDefault?`${VZ($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),X=$.description?`
165
- `+Y$(dq($.description,110)):"",H=(G,W)=>({tag:"button",text:{tag:"plain_text",content:W},type:"default",behaviors:[{type:"callback",value:{kind:G,panel_id:Z,source_id:$.sourceId,model:$.model}}]});return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,vertical_align:"center",elements:[{tag:"markdown",content:[Q,$.displayName&&$.displayName!==$.model?J1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
166
- `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[H("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:uq($,Z)}]}],...Y&&J!=="add"?[$.origin==="custom"?H("model_custom_remove","删"):H("model_remove","隐")]:[]]}]}]}function pq($,Z,J,Y=!1){let Q=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((H)=>H.provider==="dsh")}].filter((H)=>H.models.length>0),V=(H)=>H.flatMap((z,G)=>[...G?[{tag:"hr"}]:[],...mq(z,Z,J,Y)]);if(Q.length<=1)return V($);let X=[];for(let H of Q)X.push({tag:"markdown",content:`**${H.title}**`}),X.push(...V(H.models));return X}function cq($,Z,J,Y,Q){let V=Y===$.model&&Q===Z.effort,X=[Z.isDefault?"默认":"",V?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":Y$(Z.effort)}**`,X,Z.description?Y$(Z.description):""].filter(Boolean).join(`
167
- `)}]},{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 uq($,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 lq($){return $.displayName&&$.displayName!==$.model?`${Y$($.displayName)} (${J1($.model)})`:J1($.model)}function JH($,Z){return J1(YH($,Z))}function YH($,Z,J){let Y=J&&J!=="codex"?`${VZ(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function VZ($){return s0($??"codex")}function dq($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function Y$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function J1($){return"`"+$.replace(/`/g,"\\`")+"`"}function b1($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${D0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${Sq($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var Cq,bq,kq;var QH=O(()=>{j0();t6();C0();rX();Cq={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},bq={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},kq={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function XZ($){let Z=aq($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:iq($.notice)},body:{elements:[...$.notice?[nq($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(oq)]}}}function iq($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function nq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
147
+ `+Q.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!1,elements:[{tag:"markdown",content:Z0(_)},...B9(Z)&&X?[{tag:"img",img_key:X,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function j9($,Z){let J=Z.length,Q=Z.some((z)=>z.isError),Y=Z.every((z)=>z.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let z=kX(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,H=Z.map((z)=>{let W=kX(z);return W?`\`${W}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:Z0(H.join(`
148
+ `))}]}}function kX($){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 L9($,Z){let J=Z.length,Q=Z.some((z)=>z.isError),Y=Z.every((z)=>z.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let z=z1("Read",Z[0]?.input);return z?`${V} \uD83D\uDD27 Read: ${z}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,H=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:Z0(H.join(`
149
+ `))}]}}function YZ($,Z,J,Q){let Y=z1(Z,J),V=f1(Z),X=Y?`\uD83D\uDD10 等审批 · ${V}: ${Y}`:`\uD83D\uDD10 等审批 · ${V}`,H=_8(Z)?hX(J,null):j8(Z)?IX(J,null):L8(Z)?uX(J,null):K9(Z)?rX(J,null):q8(Z)?eX(J,null):t6(Z)?$H(J,null):B9(Z)?ZH(J,null):F8(Z)?dX(J,null):P8(Z)?iX(J,null):D8(Z)?nX(J,null):U8(Z)?aX(J,null):e6(Z)?oX(Z,J,null):M8(Z)?sX(J,null):A8(Z)?B8({prompt:_9(J)||"提交计划"},null):r6(Z)?B8(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!0,elements:[{tag:"markdown",content:H},{tag:"column_set",columns:[i6("✅ 允许","primary",Q,"allow"),i6("♾️ 始终允许","default",Q,"allow_always"),i6("❌ 拒绝","danger",Q,"deny")]}]}}function i6($,Z,J,Q){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:Q}}]}]}}var FF=300,wX="server_tool:";var JH=O(()=>{C0();b3()});import{execFile as hF}from"node:child_process";import{readFileSync as VZ,statfsSync as IF,statSync as QH}from"node:fs";import{cpus as gF,homedir as mF}from"node:os";import{promisify as pF}from"node:util";function uF(){try{let $=VZ("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:gF().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return B(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function lF(){try{let $=VZ("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));return X?parseInt(X[1],10)*1024:0},J=Z("MemTotal"),Q=Z("MemAvailable");if(!J)return null;let Y=Math.max(0,J-Q);return{totalBytes:J,availBytes:Q,usedBytes:Y,percent:Math.round(Y/J*100)}}catch($){return B(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function YH($,Z){try{let J=IF(Z,{bigint:!1}),Q=J.blocks*J.bsize,Y=J.bavail*J.bsize,V=Math.max(0,Q-Y);if(!Q)return null;return{label:$,path:Z,totalBytes:Q,availBytes:Y,usedBytes:V,percent:Math.round(V/Q*100)}}catch(J){return B(`sysinfo: statfs ${Z} failed: ${J}`),null}}function dF(){let $=[],Z=YH("/","/");if(Z)$.push(Z);let J=mF();if(J&&J!=="/"){let Q=!1;try{let Y=QH("/"),V=QH(J);Q=Y.dev===V.dev}catch{}if(!Q){let Y=YH("$HOME",J);if(Y)$.push(Y)}}return $}function iF(){try{let $=VZ("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function VH($,Z=2000){try{let{stdout:J}=await cF("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function XH($){return HH.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function nF(){let $=await VH(["list-units","--type=service","--all","--no-legend","--plain",...HH.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
150
+ `).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(!XH(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Q=await VH(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=iF(),V=Q.split(/\n\s*\n/),X=[],H=(z)=>{let W=parseInt(z??"0",10);if(W<=0||Y===null)return null;return Math.max(0,Y-W/1e6)};for(let z of V){let W={};for(let K of z.split(`
151
+ `)){let _=K.indexOf("=");if(_<=0)continue;W[K.slice(0,_)]=K.slice(_+1)}let G=W.Id??"";if(!XH(G))continue;X.push({name:G.replace(/\.service$/,""),active:W.ActiveState??"unknown",sub:W.SubState??"",lastActiveAgoSec:H(W.ActiveEnterTimestampMonotonic),stateAgoSec:H(W.StateChangeTimestampMonotonic)})}return X.sort((z,W)=>z.name.localeCompare(W.name)),{services:X,error:null}}async function zH(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=uF(),Z=lF(),J=dF(),{services:Q,error:Y}=await nF();return{cpu:$,mem:Z,disks:J,services:Q,servicesError:Y}}var cF,HH,q9="cc-* / codex-*";var XZ=O(()=>{h();cF=pF(hF),HH=["cc-","codex-"]});function G1($){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 HZ($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(z)=>`&#${z.charCodeAt(0)};`),Q=typeof $.used==="number"&&typeof $.total==="number"?` · ${$.used}/${$.total}`:"",Y=$.percent;if(Y===null||!Number.isFinite(Y)||Y<0||Y>100)return[{tag:"markdown",content:`**${J} · MISS${Q}**`}];let V=Math.round(Y/100*6),X=Y>=100?"red":Y>=80?"orange":"green",H=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${G1($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Y)}%${Q}**
152
+ <font color='${X}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${H}</font>`,text_size:"notation"}]}function N8($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function aF($){if($===null||!Number.isFinite($)||$<0||$>100)return"MISS";let Z=`${Math.round($)}%`;return $>=100?`<font color='red'>${Z}</font>`:$>=80?`<font color='orange'>${Z}</font>`:Z}function oF($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Q=`${N8(J)} ${aF($.percent)}`;if($.kind==="monthly")return Q;if($.unreportedFull)return`${Q}(满窗)`;return`${Q}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?G1($.resetsAt):"MISS"}`}function WH($){if(!$)return"加载中…";if($.state==="not_applicable")return"—";if($.state!=="ok"){let Q=$.state==="no_credentials"?"未登录或未配置":$.state==="rate_limited"?"API 限频":($.reason??"查询失败").replace(/^Claude 原生额度接口未返回 rate_limits 数据$/,"原生接口未返回额度");return`<font color='red'>MISS · ${N8(Q.slice(0,100))}</font>`}let Z=(Q,Y)=>{if(!Number.isFinite(Q))return"MISS";return`${Y==="USD"?"$":Y==="CNY"?"¥":N8(Y)} ${Q.toFixed(2)}`};if($.kind==="balance")return`余额 ${$.balance?Z($.balance.remaining,$.balance.currency):"MISS"}`;if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${Z($.quota.remaining,$.quota.currency)} / ${Z($.quota.limit,$.quota.currency)}`;let J=$.windows.map(oF);if(!J.length)J.push("额度 MISS");if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function GH($){return{tag:"markdown",text_size:"notation",content:`**${N8($.label)}** ${WH($.usage)}`}}var KH=()=>{};function P9($,Z){return Z}function zZ($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:E.footer,content:P9($.title,$.status)}]}}}function BH($){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 sF($){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 F9($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Q=Z%60;if(J<24)return`${J}h ${Q}m`;return`${Math.floor(J/24)}d ${J%24}h`}function $P($){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 ZP($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${q9} _n/a_`].join(`
153
+ `);let Z=[];if($.cpu){let{cores:J,load1:Q,load5:Y,load15:V}=$.cpu;Z.push(`**负载** ${Q.toFixed(2)} / ${Y.toFixed(2)} / ${V.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${BH($.mem.usedBytes)}/${BH($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${q9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${q9} _无_`);else{Z.push(`**服务** ${q9} (${$.services.length})`);for(let J of $.services){let Q=eF[J.active]??"·",Y=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${F9(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${F9(Y*1000)}前`);else X.push("从未启动");if(V!=null){let H=J.active==="failed"?"已挂":"已停";X.push(`${H} ${F9(V*1000)}`)}}else if(V!=null)X.push(`已 ${F9(V*1000)}`);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
154
+ `)}function JP($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=tF[J.status]??"·",Y=rF[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${F9(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",H=J.codexAccountName===void 0?"":` · Codex:${K1(X$(J.codexAccountName))}`;return` · ${Q} \`${J.name}\` · ${Y}${V}${X}${H}`}).join(`
155
+ `)}function R8($,Z=E.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:JP($)}]}}function QP($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${jZ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
156
+ `)}function T8($,Z=E.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:QP($)}}function E8($,Z=E.consoleHost){let J=$P($);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:ZP($)}]}}function WZ($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(Q,Y)=>`${Y==="USD"?"$":Y==="CNY"?"¥":`${Y} `}${Q.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(YP).join(" · ")}`}function YP($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function D9($){let Z=$.accountUsages;return{tag:"collapsible_panel",element_id:E.consoleUsage,expanded:!0,header:{title:{tag:"plain_text",content:"全部账号额度 · 已用 / 距重置"},background_color:"blue-50"},border:{color:"blue-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"2px",elements:Z===void 0?[{tag:"markdown",text_size:"notation",content:"加载中…"}]:Z.length?Z.map(GH):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function _H($,Z){return[T8($,Z),R8($),E8($.sysinfo),D9($)]}function x8($){let{sessionName:Z,status:J}=$,Q=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:Q},body:{elements:_H($)}}}function GZ($){return h1($.sessionName,{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${K1($.currentDisplay??"未选择")}
157
+ 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Q)=>(Q.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:E.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((Q)=>VP(Q,$.panelId))}]:[]})]})}function VP($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${X$($.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} 个模型`,Q=[$.selected?"当前账号":"",J].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${X$($.display)}**
158
+ ${Q}`}]},{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 KZ($){return h1($.sessionName,jH($))}function BZ($){return h1($.sessionName,b8($))}function U9($){return h1($.sessionName,k8($),"green")}function M9($,Z){return{tag:"collapsible_panel",element_id:E.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:X$(Z)}]}}function S8($,Z,J){return h1($,M9(Z,J),Z?"orange":"red")}function h1($,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 jH($){let Z=zP($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${LH($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
159
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?XP($.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 XP($,Z){let{sourceId:J,page:Q,totalPages:Y}=Z,V=(X,H)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:X},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:H}}]}]});return[{tag:"markdown",content:`第 ${Q+1} / ${Y} 页`},{tag:"column_set",columns:[...Q>0?[V("上一页",Q-1)]:[],...Q+1<Y?[V("下一页",Q+1)]:[]]}]}function C8($,Z="cancelled"){return h1($,{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function _Z($,Z,J){return h1($,{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
160
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function A9($,Z,J){return{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
161
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function b8($){return{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${KP($.model)}`,`当前: ${LH($.currentModel,$.currentEffort)}`].join(`
162
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>WP($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function k8($){return{tag:"collapsible_panel",element_id:E.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",K1(qH($.model,$.effort,$.provider)),X$($.scope)].join(`
163
+ `)}]}}function HP($,Z,J,Q=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${X$($.displayName)}** · 未配置
164
+ ${X$($.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 Y=$.displayName&&$.displayName!==$.model?`**${X$($.displayName)}**`:`**${K1($.model)}**`,V=[$.isDefault?`${jZ($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),X=$.description?`
165
+ `+X$(BP($.description,110)):"",H=(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:[Y,$.displayName&&$.displayName!==$.model?K1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
166
+ `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[H("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:GP($,Z)}]}],...Q&&J!=="add"?[$.origin==="custom"?H("model_custom_remove","删"):H("model_remove","隐")]:[]]}]}]}function zP($,Z,J,Q=!1){let Y=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((H)=>H.provider==="dsh")}].filter((H)=>H.models.length>0),V=(H)=>H.flatMap((z,W)=>[...W?[{tag:"hr"}]:[],...HP(z,Z,J,Q)]);if(Y.length<=1)return V($);let X=[];for(let H of Y)X.push({tag:"markdown",content:`**${H.title}**`}),X.push(...V(H.models));return X}function WP($,Z,J,Q,Y){let V=Q===$.model&&Y===Z.effort,X=[Z.isDefault?"默认":"",V?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${Z.effort==="default"?"模型默认":X$(Z.effort)}**`,X,Z.description?X$(Z.description):""].filter(Boolean).join(`
167
+ `)}]},{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 GP($,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 KP($){return $.displayName&&$.displayName!==$.model?`${X$($.displayName)} (${K1($.model)})`:K1($.model)}function LH($,Z){return K1(qH($,Z))}function qH($,Z,J){let Q=J&&J!=="codex"?`${jZ(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function jZ($){return y0($??"codex")}function BP($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function X$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function K1($){return"`"+$.replace(/`/g,"\\`")+"`"}function I1($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${U0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${sF($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var tF,rF,eF;var FH=O(()=>{G0();XZ();C0();KH();tF={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},rF={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},eF={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function LZ($){let Z=LP($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:_P($.notice)},body:{elements:[...$.notice?[jP($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(qP)]}}}function _P($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function jP($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
168
168
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
169
- `)}}function aq($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${N8("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function oq($){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:`**${N8($.slug)}**
169
+ `)}}function LP($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${w8("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function qP($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Q=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${w8($.slug)}**
170
170
  ${Z} · ${J}
171
- ${N8($.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 P9($){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,N8($.branch),...$.body?[$.body]:[]].join(`
172
- `)}]}}}function N8($){return"`"+$.replace(/`/g,"\\`")+"`"}function zZ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
171
+ ${w8($.branch)}`}]}];if($.mounted||$.chatId)Q.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:Q}]}function O9($){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,w8($.branch),...$.body?[$.body]:[]].join(`
172
+ `)}]}}}function w8($){return"`"+$.replace(/`/g,"\\`")+"`"}function FZ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
173
173
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
174
- 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:sq($.notice)});if(!$.entries.length)V.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{V.push({tag:"markdown",content:Q});for(let X of $.entries)V.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${BZ(X.ts)}**
175
- ${Y1(X.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:X.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 GZ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
176
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${BZ(J.ts)}**
177
- ${Y1(J.preview.slice(0,60)||"(无摘要)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"分支"},type:"primary",behaviors:[{type:"callback",value:{kind:"temp_resume_select",panel_id:$.panelId,choice_id:J.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs 独立分支 · ${$.projectName}`},template:"purple"},body:{elements:Z}}}function WZ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
174
+ 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:FP($.notice)});if(!$.entries.length)V.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{V.push({tag:"markdown",content:Y});for(let X of $.entries)V.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${MZ(X.ts)}**
175
+ ${B1(X.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:Q,panel_id:$.panelId,choice_id:X.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 PZ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
176
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${MZ(J.ts)}**
177
+ ${B1(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 DZ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
178
178
  …(截断)`:J.body;return`${J.path} (${J.tool})
179
- ${Y}`}).join(`
179
+ ${Q}`}).join(`
180
180
 
181
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function Q1($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${HZ($.message)}`}]}}}function KZ($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Y=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Q=$.selectedPreview.slice(0,80)||"(无摘要)",V=$.sourceStatus?` · 状态 ${Y1($.sourceStatus)}`:"",X=$.bindingState==="changed"?["**当前群**",`新会话 ${Y1(R8($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
181
+ `);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?"✅":"❌"} ${qZ($.message)}`}]}}}function UZ($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Q=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Y=$.selectedPreview.slice(0,80)||"(无摘要)",V=$.sourceStatus?` · 状态 ${B1($.sourceStatus)}`:"",X=$.bindingState==="changed"?["**当前群**",`新会话 ${B1(y8($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
182
182
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
183
- `):$.bindingState==="unchanged"?[`${HZ($.message)}`,"",`本群原绑定 ${Y1(R8($.previousSessionId))};源会话未修改。`].join(`
184
- `):[`${HZ($.message)}`,"",`后端返回会话 ${Y1(R8($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
185
- `);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}**`,`**${BZ($.selectedTs)}**${V}`,Y1(Q),`源会话 ${Y1(R8($.sourceSessionId))}`].join(`
186
- `)},{tag:"markdown",content:X}]}}}function BZ($){let Z=new Date($),J=(Y)=>String(Y).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function Y1($){return"`"+VH($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function R8($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function HZ($){return VH($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function VH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function sq($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
183
+ `):$.bindingState==="unchanged"?[`${qZ($.message)}`,"",`本群原绑定 ${B1(y8($.previousSessionId))};源会话未修改。`].join(`
184
+ `):[`${qZ($.message)}`,"",`后端返回会话 ${B1(y8($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
185
+ `);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:`${Q} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${MZ($.selectedTs)}**${V}`,B1(Y),`源会话 ${B1(y8($.sourceSessionId))}`].join(`
186
+ `)},{tag:"markdown",content:X}]}}}function MZ($){let Z=new Date($),J=(Q)=>String(Q).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function B1($){return"`"+PH($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function y8($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function qZ($){return PH($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function PH($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function FP($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
187
187
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
188
- `)}function XH($){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(`
188
+ `)}function DH($){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
189
  ---
190
- `);return""}function _Z($,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:XH(Z)}]}function LZ($){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?[eq($.notice)]:[],{tag:"markdown",element_id:T.tasklistPanel,content:tq($)},rq($)]}}}function tq($){let Z=[`项目:${jZ($.projectName)}`,`清单:${jZ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
191
- `);if(Z.push("","已启用"),Z.push(`GUID:${jZ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
192
- `)}function rq($){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 eq($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
193
- `).map((J)=>`<font color='${Z}'>${$F(J)||" "}</font>`).join(`
194
- `)}}function jZ($){return"`"+$.replace(/`/g,"\\`")+"`"}function $F($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var HH=O(()=>{C0()});import{createHash as ZF}from"node:crypto";function qZ($){let Z=[{tag:"markdown",element_id:T.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
195
- `)}];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(`
196
- `)}]});return Z.push(...$.catalog.map(QF),VF($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function FZ($){return{tag:"collapsible_panel",element_id:T8($.runId),header:{title:{tag:"plain_text",content:E8($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${N$($.description??"说明 MISS")}**`,KH($).content,`**任务说明**
197
- ${zF($.prompt)}`,...$.workers.map((Z)=>WH(Z,BH($.workers.length)).content)].join(`
198
-
199
- `)}]}}function T8($){return`ar_${ZF("sha256").update($).digest("hex").slice(0,16)}`}function DZ($){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 WH($,Z=GH){let J=XF($),Y=[`模型 ${k1($.model)} · 推理 ${k1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${D0($.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)=>k1(V.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",$0($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",GF($0($.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"?"→":"·",X=Q.tool==="tool error"?"工具执行失败":Q.tool==="tool result"?"工具执行完成":Q.tool;Y.push(`- ${V} ${k1(X)} ${N$(jH(Q.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${N$($.identityName)}**`,...Y].join(`
200
- `)}}function KH($){let Z=$.workers.filter((W)=>W.status==="completed").length,J=$.workers.filter((W)=>W.status==="failed").length,Y=$.workers.filter((W)=>W.status==="needs_input").length,Q=$.workers.filter((W)=>W.status==="running").length,V=$.workers.filter((W)=>W.status==="queued").length,X=$.workers.filter((W)=>W.status==="cancelled").length,H=[Q?`执行中 ${Q}`:"",V?`排队 ${V}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",X?`已取消 ${X}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${_H($)}** · 完成 ${Z}/${$.workers.length}`,...H.length?[H.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${D0(z/1000)}`]:[],...$.error?[N$($.error)]:[]].join(`
201
- `)}}function BH($){let Z=Math.max(1,Math.floor($));return Math.min(GH,Math.max(YF,Math.floor(JF/Z)))}function E8($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${_H($)} · ${jH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function QF($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${N$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${k1($.id)}
202
- ${k1($.model)} · 默认 ${k1($.defaultEffort??"MISS")} · ${N$(J)}`].join(`
203
- `)}}function VF($){return{tag:"column_set",columns:[PZ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),PZ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),PZ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function PZ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function XF($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function HF($){return $==="completed"||$==="failed"||$==="cancelled"}function _H($){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)=>HF(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function zF($){let Z=$0($);if(Z.length<=zH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,zH-J.length-2)}
204
-
205
- ${J}`}function GF($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
206
-
207
- ${J}`}function k1($){return"`"+$.replace(/`/g,"\\`")+"`"}function N$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function jH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var zH=1e4,JF=48000,GH=8000,YF=512;var LH=O(()=>{C0()});function w1($){return WF.has($)?$:null}function x8($){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 y1($){return String($?.subject??$?.content??"").trim()}function MZ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function FH($){return`subj:${$}`}function PH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function jF($){let Z=y1($);if(!Z)return null;return{id:m2($)||FH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:MZ($)??"pending"}}function UZ($,Z,J,Y){if(Z==="TaskList"){let Q=x8(Y),V=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(V===null)return $;let X=[];for(let H of V){let z=jF(H);if(z)X.push(z)}return X}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let G=x8(Y),W=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,K=$;return Q.forEach((_,L)=>{let j=y1(_);if(!j)return;let q=W?.[L],F=q&&m2(q)||PH(Y??"");K=qH(K,F,j,_)}),K}let V=x8(Y),X=V?.task??V,H=m2(X)||PH(Y??""),z=y1(X)||y1(J);if(!z)return $;return qH($,H,z,J)}if(Z==="TaskUpdate"){let Q=m2(J);if(!Q)return $;let V=MZ(J);if(V==="deleted")return $.filter((H)=>H.id!==Q);let X=y1(J);if($.some((H)=>H.id===Q))return $.map((H)=>H.id===Q?{...H,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:H);return $}if(Z==="TaskGet"){let Q=x8(Y),V=Q?.task??Q,X=m2(V)||m2(J);if(!X)return $;let H=$.find((W)=>W.id===X),z=y1(V)||H?.subject||y1(J);if(!z)return $;let G={id:X,subject:z,description:typeof V?.description==="string"?V.description:H?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:H?.activeForm,status:MZ(V)??H?.status??"pending"};return H?$.map((W)=>W.id===X?G:W):[...$,G]}return $}function qH($,Z,J,Y){let Q=Z||FH(J),V={...typeof Y?.activeForm==="string"&&Y.activeForm?{activeForm:Y.activeForm}:{},...typeof Y?.description==="string"&&Y.description?{description:Y.description}:{}};if($.some((X)=>X.id===Q))return $.map((X)=>X.id===Q?{...X,id:Q,subject:J,...V}:X);return[...$,{id:Q,subject:J,status:"pending",...V}]}function AZ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let X=BF[V.status];J.set(X,(J.get(X)??0)+1)}let Q=["进行中","待办","完成"].map((V)=>J.has(V)?`${V} ${J.get(V)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function DH($,Z){let J=$.filter((X)=>X.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(X)=>{let H=parseInt(X,10);return Number.isNaN(H)?Number.MAX_SAFE_INTEGER:H},V=[...J].sort((X,H)=>{let z=Q(X.id)-Q(H.id);return z!==0?z:X.id.localeCompare(H.id)});for(let X of V.slice(0,12)){let H=_F[X.status],z=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Y.push(`- ${H} ${z||"(空)"}`)}if(V.length>12)Y.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
208
- `)}function V1($,Z,J,Y){let Q=KF[J.name],V=AZ(Z),X=`${J.status} \uD83D\uDD27 ${Q}: ${V}`;return{tag:"collapsible_panel",element_id:T.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:DH(Z,Y)}]}}function v1($){return{tag:"collapsible_panel",element_id:T.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${AZ($)}`}},expanded:!0,elements:[{tag:"markdown",content:DH($)}]}}var WF,KF,BF,_F;var MH=O(()=>{C0();WF=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);KF={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},BF={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},_F={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var Q$=O(()=>{C0();s3();FX();uX();QH();HH();LH();MH();$6()});function UH($){if(!$||typeof $!=="object")return!1;let Z=$.response?.status??$.status,J=$.response?.data?.code??$.code;if(J===99991400||J===230020||J===1061045||LF.has(Z))return!0;if(typeof Z==="number"&&Z>=400)return!1;if(PF.has(J)||$.name==="TimeoutError")return!0;return $.cause!==$&&UH($.cause)}function qF($){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 f1($,Z){for(let J=0;;J++)try{return await Z()}catch(Y){let Q=Math.max(OZ[J]??0,qF(Y)),V=UH(Y)&&J<OZ.length&&Q<=60000;if(B(`feishu: ${$} attempt ${J+1}/${OZ.length+1} failed: ${Y}; ${V?`retry in ${Q}ms`:"FINAL"}`),!V)throw Y;await new Promise((X)=>setTimeout(X,Q))}}async function p2($,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 R$(`${Z} HTTP ${$.status}: invalid JSON — ${J.slice(0,200)}`,$.status,void 0,Y)}if(!$.ok||Q?.code!==0)throw new R$(`${Z} HTTP ${$.status} code=${Q?.code??"MISS"} msg=${Q?.msg??"MISS"}`,$.status,Q?.code,Y);return Q}var OZ,LF,PF,R$;var S8=O(()=>{f();OZ=[1000,4000],LF=new Set([408,429,500,502,503,504]),PF=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"]);R$=class R$ extends Error{status;code;retryAfter;constructor($,Z,J,Y){super($);this.status=Z;this.code=J;this.retryAfter=Y;this.name="FeishuRequestError"}}});function DF($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!FF.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 F9{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 AH($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class RZ{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 NZ($){if(Array.isArray($))return`[${$.map(NZ).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)}:${NZ(J)}`).join(",")}}`}function MF($){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${NZ(V)}`}function UF($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${MF($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function AF(){return new Promise(($)=>setTimeout($,0))}function q9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function OH($){let Z=$.afterAck??AF,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=DF(Q);if(V)return $.responses.invalid(Q,V);let X=UF(Q),H=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],z=$.deduper.claimAll(H);if(z==="inflight")return $.responses.inflight(Q);if(z==="completed")return $.responses.completed(Q);let G=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(_){$.deduper.failAll(H),J(_);return}let W;try{W=await $.execute(Q)}catch(_){q9($.deduper,X,!0),await Y(()=>$.presentExecutionFailure(Q,_));return}await Y(async()=>{try{await $.present(Q,W)}catch(_){await $.presentPresentationFailure(Q,_)}});let K;try{K=$.completion(Q,W)}catch(_){q9($.deduper,X,!1),J(_);return}if(K){let _=K.then((L)=>{q9($.deduper,X,L==="complete")},(L)=>{q9($.deduper,X,!1),J(L)});$.track(_);return}q9($.deduper,X,$.businessSucceeded(Q,W))});if(!G.accepted)return $.deduper.failAll(H),$.responses.closed(Q);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Q)}}}var FF;var TZ=O(()=>{FF=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 OF}from"node:async_hooks";class NH{actor=new F9;context=new OF;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 B$($,Z){return NF.run($,Z)}var NF;var EZ=O(()=>{TZ();NF=new NH});import{execFileSync as RF}from"node:child_process";import{existsSync as h1,readdirSync as TF,readFileSync as EF,realpathSync as xZ,statSync as xF}from"node:fs";import{dirname as SF,join as TH,resolve as b8}from"node:path";async function k8($,Z){let J=xZ($),Y=process.platform==="win32"?J.toLowerCase():J,Q=C8.get(Y)??Promise.resolve(),V,X=new Promise((z)=>{V=z}),H=Q.catch(()=>{}).then(()=>X);C8.set(Y,H),await Q.catch(()=>{});try{return await Z()}finally{if(V(),C8.get(Y)===H)C8.delete(Y)}}function I1($){let Z=$.trim();if(!CF.test(Z))return null;return Z}function y8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function u2($,Z){return`${$}[${Z}]`}function EH($){return`${c2}${$}`}function l2($,Z,J){return TH(SF($),u2(Z,J))}function xH($,Z,J){let Y=bF($,Z,J);if(!Y)return null;let Q=EF(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function SH($,Z){CZ($);let J=N0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${c2}`]).split(`
209
- `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(c2)),Y=bZ($),Q=[];for(let V of J){let X=V.slice(c2.length);if(!I1(X))continue;let H=u2(Z,X),z=l2($,Z,X),G=Y.get(V)??null,W=!!G&&h1(G),K=yH($,V,W),_={slug:X,chatName:H,branch:V,state:K,expectedPath:z,worktreePath:W?G:null,mounted:W,dirtyCount:null,statusLine:null,error:null};if(G&&h1(G))try{let j=N0(G,["status","--porcelain=v1","--branch"]).split(`
210
- `).filter(Boolean);_.statusLine=j[0]?.startsWith("## ")?j[0].slice(3):null,_.dirtyCount=j.filter((q)=>!q.startsWith("## ")).length}catch(L){_.error=kZ(L)}Q.push(_)}return Q.sort((V,X)=>V.slug.localeCompare(X.slug))}function CH($,Z,J){let Y=I1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);CZ($);let Q=EH(Y),V=u2(Z,Y),X=l2($,Z,Y),H=vF($,Q),z=bZ($).get(Q)??null,G=H&&!z&&yH($,Q,!1)==="merged"?N0($,["rev-parse","HEAD"]).trim():null;if(z){if(b8(z)!==b8(X))throw Error(`branch ${Q} is already mounted at ${z}`);return kH(X,Q),{slug:Y,chatName:V,branch:Q,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(h1(X)){if(!xF(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!H)throw Error(`${X} already exists while branch ${Q} does not`)}if(H){if(N0($,["worktree","add",X,Q]),G)N0(X,["rebase",G]);return{slug:Y,chatName:V,branch:Q,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return N0($,["worktree","add","-b",Q,X,"HEAD"]),{slug:Y,chatName:V,branch:Q,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function bH($,Z,J){let Y=SZ($,Z,J);if(!h1(Y.worktreePath))return Y;return N0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function SZ($,Z,J){let Y=I1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);CZ($);let Q=EH(Y),V=u2(Z,Y),X=l2($,Z,Y),z=bZ($).get(Q)??null??X;if(!h1(z))return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1};kH(z,Q);let G=N0(z,["status","--porcelain=v1"]).split(`
211
- `).filter(Boolean);if(G.length>0){let W=G.slice(0,8).join(`
190
+ `);return""}function AZ($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Q)=>Q&&typeof Q==="object").map((Q)=>({tool:$,path:typeof Q.path==="string"&&Q.path?Q.path:"?",body:typeof Q.diff==="string"?Q.diff:typeof Q.unified_diff==="string"?Q.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:DH(Z)}]}function NZ($){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?[UP($.notice)]:[],{tag:"markdown",element_id:E.tasklistPanel,content:PP($)},DP($)]}}}function PP($){let Z=[`项目:${OZ($.projectName)}`,`清单:${OZ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
191
+ `);if(Z.push("","已启用"),Z.push(`GUID:${OZ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
192
+ `)}function DP($){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 UP($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
193
+ `).map((J)=>`<font color='${Z}'>${MP(J)||" "}</font>`).join(`
194
+ `)}}function OZ($){return"`"+$.replace(/`/g,"\\`")+"`"}function MP($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var UH=O(()=>{C0()});import{createHash as AP}from"node:crypto";function TZ($){let Z=[{tag:"markdown",element_id:E.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
195
+ `)}];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)=>`- **${x$(J.display)}**:${x$(J.reason)}`).join(`
196
+ `)}]});return Z.push(...$.catalog.map(RP),TP($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function EZ($){return{tag:"collapsible_panel",element_id:v8($.runId),header:{title:{tag:"plain_text",content:f8($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${x$($.description??"说明 MISS")}**`,NH($).content,`**任务说明**
197
+ ${SP($.prompt)}`,...$.workers.map((Z)=>OH(Z,RH($.workers.length)).content)].join(`
198
+
199
+ `)}]}}function v8($){return`ar_${AP("sha256").update($).digest("hex").slice(0,16)}`}function xZ($){if($.length===1)return $[0].summary;let Z=$.filter((Y)=>Y.terminal).length,J=$.filter((Y)=>Y.status==="failed").length,Q=$.filter((Y)=>Y.status==="needs_input"||Y.status==="paused").length;return`\uD83E\uDDE0 委派任务 · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Q?` · 待处理 ${Q}`:""}`}function OH($,Z=AH){let J=EP($),Q=[`模型 ${g1($.model)} · 推理 ${g1($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${U0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Q.push("",x$($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let Y of $.pendingInput.questions)if(Q.push(`- ${x$(Y.question)}`),Y.options.length)Q.push(` 选项:${Y.options.map((V)=>g1(V.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",Z0($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",CP(Z0($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3)){let V=Y.tool==="tool error"?"❌":Y.phase==="completed"?"✓":Y.phase==="started"?"→":"·",X=Y.tool==="tool error"?"工具执行失败":Y.tool==="tool result"?"工具执行完成":Y.tool;Q.push(`- ${V} ${g1(X)} ${x$(EH(Y.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${x$($.identityName)}**`,...Q].join(`
200
+ `)}}function NH($){let Z=$.workers.filter((G)=>G.status==="completed").length,J=$.workers.filter((G)=>G.status==="failed").length,Q=$.workers.filter((G)=>G.status==="needs_input").length,Y=$.workers.filter((G)=>G.status==="running").length,V=$.workers.filter((G)=>G.status==="queued").length,X=$.workers.filter((G)=>G.status==="cancelled").length,H=[Y?`执行中 ${Y}`:"",V?`排队 ${V}`:"",Q?`待答 ${Q}`:"",J?`失败 ${J}`:"",X?`已取消 ${X}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${TH($)}** · 完成 ${Z}/${$.workers.length}`,...H.length?[H.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${U0(z/1000)}`]:[],...$.error?[x$($.error)]:[]].join(`
201
+ `)}}function RH($){let Z=Math.max(1,Math.floor($));return Math.min(AH,Math.max(NP,Math.floor(OP/Z)))}function f8($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${TH($)} · ${EH($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function RP($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${x$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${g1($.id)}
202
+ ${g1($.model)} · 默认 ${g1($.defaultEffort??"MISS")} · ${x$(J)}`].join(`
203
+ `)}}function TP($){return{tag:"column_set",columns:[RZ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),RZ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),RZ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function RZ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function EP($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function xP($){return $==="completed"||$==="failed"||$==="cancelled"}function TH($){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)=>xP(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function SP($){let Z=Z0($);if(Z.length<=MH)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,MH-J.length-2)}
204
+
205
+ ${J}`}function CP($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
206
+
207
+ ${J}`}function g1($){return"`"+$.replace(/`/g,"\\`")+"`"}function x$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function EH($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var MH=1e4,OP=48000,AH=8000,NP=512;var xH=O(()=>{C0()});function p1($){return bP.has($)?$:null}function h8($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function d2($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function m1($){return String($?.subject??$?.content??"").trim()}function SZ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function bH($){return`subj:${$}`}function SH($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function vP($){let Z=m1($);if(!Z)return null;return{id:d2($)||bH(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:SZ($)??"pending"}}function CZ($,Z,J,Q){if(Z==="TaskList"){let Y=h8(Q),V=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(V===null)return $;let X=[];for(let H of V){let z=vP(H);if(z)X.push(z)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let W=h8(Q),G=Array.isArray(W?.tasks)?W.tasks:Array.isArray(W)?W:null,K=$;return Y.forEach((_,L)=>{let j=m1(_);if(!j)return;let q=G?.[L],P=q&&d2(q)||SH(Q??"");K=CH(K,P,j,_)}),K}let V=h8(Q),X=V?.task??V,H=d2(X)||SH(Q??""),z=m1(X)||m1(J);if(!z)return $;return CH($,H,z,J)}if(Z==="TaskUpdate"){let Y=d2(J);if(!Y)return $;let V=SZ(J);if(V==="deleted")return $.filter((H)=>H.id!==Y);let X=m1(J);if($.some((H)=>H.id===Y))return $.map((H)=>H.id===Y?{...H,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:H);return $}if(Z==="TaskGet"){let Y=h8(Q),V=Y?.task??Y,X=d2(V)||d2(J);if(!X)return $;let H=$.find((G)=>G.id===X),z=m1(V)||H?.subject||m1(J);if(!z)return $;let W={id:X,subject:z,description:typeof V?.description==="string"?V.description:H?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:H?.activeForm,status:SZ(V)??H?.status??"pending"};return H?$.map((G)=>G.id===X?W:G):[...$,W]}return $}function CH($,Z,J,Q){let Y=Z||bH(J),V={...typeof Q?.activeForm==="string"&&Q.activeForm?{activeForm:Q.activeForm}:{},...typeof Q?.description==="string"&&Q.description?{description:Q.description}:{}};if($.some((X)=>X.id===Y))return $.map((X)=>X.id===Y?{...X,id:Y,subject:J,...V}:X);return[...$,{id:Y,subject:J,status:"pending",...V}]}function bZ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let X=wP[V.status];J.set(X,(J.get(X)??0)+1)}let Y=["进行中","待办","完成"].map((V)=>J.has(V)?`${V} ${J.get(V)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function kH($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let H=parseInt(X,10);return Number.isNaN(H)?Number.MAX_SAFE_INTEGER:H},V=[...J].sort((X,H)=>{let z=Y(X.id)-Y(H.id);return z!==0?z:X.id.localeCompare(H.id)});for(let X of V.slice(0,12)){let H=yP[X.status],z=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${H} ${z||"(空)"}`)}if(V.length>12)Q.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
208
+ `)}function j1($,Z,J,Q){let Y=kP[J.name],V=bZ(Z),X=`${J.status} \uD83D\uDD27 ${Y}: ${V}`;return{tag:"collapsible_panel",element_id:E.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:kH(Z,Q)}]}}function c1($){return{tag:"collapsible_panel",element_id:E.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${bZ($)}`}},expanded:!0,elements:[{tag:"markdown",content:kH($)}]}}var bP,kP,wP,yP;var wH=O(()=>{C0();bP=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);kP={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},wP={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},yP={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var H$=O(()=>{C0();V8();bX();JH();FH();UH();xH();wH();W6()});function yH($){if(!$||typeof $!=="object")return!1;let Z=$.response?.status??$.status,J=$.response?.data?.code??$.code;if(J===99991400||J===230020||J===1061045||fP.has(Z))return!0;if(typeof Z==="number"&&Z>=400)return!1;if(hP.has(J)||$.name==="TimeoutError")return!0;return $.cause!==$&&yH($.cause)}function IP($){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),Q=Number.isFinite(J)?J*1000:Date.parse(Z)-Date.now();return Number.isFinite(Q)?Math.max(0,Q):0}async function u1($,Z){for(let J=0;;J++)try{return await Z()}catch(Q){let Y=Math.max(kZ[J]??0,IP(Q)),V=yH(Q)&&J<kZ.length&&Y<=60000;if(B(`feishu: ${$} attempt ${J+1}/${kZ.length+1} failed: ${Q}; ${V?`retry in ${Y}ms`:"FINAL"}`),!V)throw Q;await new Promise((X)=>setTimeout(X,Y))}}async function i2($,Z){let J=await $.text(),Q=$.headers.get("retry-after")??$.headers.get("x-ogw-ratelimit-reset"),Y;try{Y=JSON.parse(J)}catch{throw new S$(`${Z} HTTP ${$.status}: invalid JSON — ${J.slice(0,200)}`,$.status,void 0,Q)}if(!$.ok||Y?.code!==0)throw new S$(`${Z} HTTP ${$.status} code=${Y?.code??"MISS"} msg=${Y?.msg??"MISS"}`,$.status,Y?.code,Q);return Y}var kZ,fP,hP,S$;var I8=O(()=>{h();kZ=[1000,4000],fP=new Set([408,429,500,502,503,504]),hP=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"]);S$=class S$ extends Error{status;code;retryAfter;constructor($,Z,J,Q){super($);this.status=Z;this.code=J;this.retryAfter=Q;this.name="FeishuRequestError"}}});function mP($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!gP.has(J))return`不支持的操作: ${J}`;let Q=J==="notify_callback"||J==="notify_reply"||J==="notify_reply_cancel";if(!Q&&!String($?.context?.open_chat_id??""))return"回调缺少 chat_id,操作未执行";if(!Q&&!String($?.context?.open_message_id??""))return"回调缺少原卡 message_id,操作未执行";if(J==="permission"&&!["allow","allow_always","deny"].includes(String(Z.decision??"")))return"无效的权限决定,操作未执行";return null}class R9{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 Y=(this.tails.get(J)??Promise.resolve()).then(Z),V;return V=Y.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===V)this.tails.delete(J)}),this.tails.set(J,V),{accepted:!0,completion:Y}}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 vH($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class yZ{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 wZ($){if(Array.isArray($))return`[${$.map(wZ).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)}:${wZ(J)}`).join(",")}}`}function pP($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Q=String($?.context?.open_chat_id??""),Y=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`${Q}\x00${Y}\x00${J}\x00${wZ(V)}`}function cP($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${pP($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function uP(){return new Promise(($)=>setTimeout($,0))}function N9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function fH($){let Z=$.afterAck??uP,J=(Y)=>{try{$.onBackgroundError?.(Y)}catch{}},Q=async(Y)=>{try{await Y()}catch(V){J(V)}};return{accept(Y){if(!$.actor.isAccepting())return $.responses.closed(Y);let V=mP(Y);if(V)return $.responses.invalid(Y,V);let X=cP(Y),H=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],z=$.deduper.claimAll(H);if(z==="inflight")return $.responses.inflight(Y);if(z==="completed")return $.responses.completed(Y);let W=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(_){$.deduper.failAll(H),J(_);return}let G;try{G=await $.execute(Y)}catch(_){N9($.deduper,X,!0),await Q(()=>$.presentExecutionFailure(Y,_));return}await Q(async()=>{try{await $.present(Y,G)}catch(_){await $.presentPresentationFailure(Y,_)}});let K;try{K=$.completion(Y,G)}catch(_){N9($.deduper,X,!1),J(_);return}if(K){let _=K.then((L)=>{N9($.deduper,X,L==="complete")},(L)=>{N9($.deduper,X,!1),J(L)});$.track(_);return}N9($.deduper,X,$.businessSucceeded(Y,G))});if(!W.accepted)return $.deduper.failAll(H),$.responses.closed(Y);return $.track(W.completion),W.completion.catch(J),$.responses.accepted(Y)}}}var gP;var vZ=O(()=>{gP=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 lP}from"node:async_hooks";class hH{actor=new R9;context=new lP;run($,Z){let J=this.context.getStore();if(J?.active&&J.chatId===$)return Z();return this.actor.enqueue($,async()=>{let Q={chatId:$,active:!0};try{return await this.context.run(Q,Z)}finally{Q.active=!1}})}}function j$($,Z){return dP.run($,Z)}var dP;var fZ=O(()=>{vZ();dP=new hH});import{execFileSync as iP}from"node:child_process";import{existsSync as l1,readdirSync as nP,readFileSync as aP,realpathSync as hZ,statSync as oP}from"node:fs";import{dirname as sP,join as gH,resolve as m8}from"node:path";async function p8($,Z){let J=hZ($),Q=process.platform==="win32"?J.toLowerCase():J,Y=g8.get(Q)??Promise.resolve(),V,X=new Promise((z)=>{V=z}),H=Y.catch(()=>{}).then(()=>X);g8.set(Q,H),await Y.catch(()=>{});try{return await Z()}finally{if(V(),g8.get(Q)===H)g8.delete(Q)}}function d1($){let Z=$.trim();if(!tP.test(Z))return null;return Z}function c8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function a2($,Z){return`${$}[${Z}]`}function mH($){return`${n2}${$}`}function o2($,Z,J){return gH(sP($),a2(Z,J))}function pH($,Z,J){let Q=rP($,Z,J);if(!Q)return null;let Y=aP(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function cH($,Z){gZ($);let J=N0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${n2}`]).split(`
209
+ `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(n2)),Q=mZ($),Y=[];for(let V of J){let X=V.slice(n2.length);if(!d1(X))continue;let H=a2(Z,X),z=o2($,Z,X),W=Q.get(V)??null,G=!!W&&l1(W),K=iH($,V,G),_={slug:X,chatName:H,branch:V,state:K,expectedPath:z,worktreePath:G?W:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(W&&l1(W))try{let j=N0(W,["status","--porcelain=v1","--branch"]).split(`
210
+ `).filter(Boolean);_.statusLine=j[0]?.startsWith("## ")?j[0].slice(3):null,_.dirtyCount=j.filter((q)=>!q.startsWith("## ")).length}catch(L){_.error=pZ(L)}Y.push(_)}return Y.sort((V,X)=>V.slug.localeCompare(X.slug))}function uH($,Z,J){let Q=d1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);gZ($);let Y=mH(Q),V=a2(Z,Q),X=o2($,Z,Q),H=JD($,Y),z=mZ($).get(Y)??null,W=H&&!z&&iH($,Y,!1)==="merged"?N0($,["rev-parse","HEAD"]).trim():null;if(z){if(m8(z)!==m8(X))throw Error(`branch ${Y} is already mounted at ${z}`);return dH(X,Y),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(l1(X)){if(!oP(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!H)throw Error(`${X} already exists while branch ${Y} does not`)}if(H){if(N0($,["worktree","add",X,Y]),W)N0(X,["rebase",W]);return{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return N0($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function lH($,Z,J){let Q=IZ($,Z,J);if(!l1(Q.worktreePath))return Q;return N0($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function IZ($,Z,J){let Q=d1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);gZ($);let Y=mH(Q),V=a2(Z,Q),X=o2($,Z,Q),z=mZ($).get(Y)??null??X;if(!l1(z))return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1};dH(z,Y);let W=N0(z,["status","--porcelain=v1"]).split(`
211
+ `).filter(Boolean);if(W.length>0){let G=W.slice(0,8).join(`
212
212
  `);throw Error(`worktree has uncommitted changes:
213
- ${W}`)}return{slug:Y,chatName:V,branch:Q,worktreePath:z,removedWorktree:!1}}function CZ($){if(!h1($))throw Error(`project directory does not exist: ${$}`);let Z=N0($,["rev-parse","--show-toplevel"]).trim();if(xZ(Z)!==xZ($))throw Error(`${$} is not the git repository root (${Z})`)}function kH($,Z){let J=N0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function bF($,Z,J){let Y=kF($);if(!Y?.startsWith(c2))return null;let Q=Y.slice(c2.length);if(!I1(Q))throw Error(`invalid worktree branch "${Y}"`);let V=l2(Z,J,Q);if(b8($)!==b8(V))return null;let X=wF($,yF(Q));return X?{path:X,slug:Q}:null}function kF($){if(!h1($))return null;try{return N0($,["branch","--show-current"]).trim()||null}catch(Z){if(fF(Z))return null;throw Z}}function yF($){return $.split("-",1)[0]??$}function wF($,Z){let J=`agents.${Z}.md`,Y=TF($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?TH($,Y[0]):null}function vF($,Z){try{return N0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function yH($,Z,J){let Y=N0($,["rev-parse",Z]).trim(),Q=N0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(RH($,Z,"HEAD"))return"merged";if(RH($,"HEAD",Z))return"active";return"stale"}function RH($,Z,J){try{return N0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function bZ($){let Z=new Map,J=N0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
214
- `)){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 N0($,Z){try{return RF("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(kZ(J))}}function kZ($){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 fF($){return/not a git repository/i.test(kZ($))}var c2="work/",CF,C8;var yZ=O(()=>{CF=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,C8=new Map});import{lstatSync as IF,realpathSync as gF,statSync as mF}from"node:fs";import{basename as pF,dirname as wH,isAbsolute as cF,join as vH,resolve as uF}from"node:path";function lF($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function wZ($,Z,J){let Y=lF($),Q=y8(Y),V=J[Q]?.cwd?.trim()||vH(Z,Q);if(Y===Q)return V;return l2(V,Q,Y.slice(Q.length+1,-1))}function T$($){if(!cF($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=fH(uF($));return process.platform==="win32"?Z.toLowerCase():Z}function fH($){try{let Z=gF($);if(!mF(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||wH($)===$)throw Z;try{if(IF($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return vH(fH(wH($)),pF($))}}function hH($,Z,J){let Y=T$($),Q,V=new Map;for(let[X,H]of Object.entries(J)){if(T$(wZ(X,Z,J))!==Y)continue;Q??={cwd:$};for(let z of["settingSources","strictMcp","tools","loadProjectMcp"]){let G=H[z];if(G===void 0)continue;if(Q[z]!==void 0&&Q[z]!==G)throw Error(`同一工作目录的项目配置冲突: ${V.get(z)} / ${X}, ${z} (${$})`);Object.assign(Q,{[z]:G}),V.set(z,X)}}return Q}var w8=O(()=>{yZ()});async function vZ($){let Z=await IZ("feishu chat.get",()=>X0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)v8("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 fZ($,Z){let J=await IZ("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)v8("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 hZ($){let Z=await IZ("feishu tasklist.delete",()=>X0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)v8("feishu tasklist.delete",Z)}function IH($,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",X=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,H=Array.isArray(X)?X.map((z)=>z?.scope??z?.subject??z?.name??z).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${V}${H?` missing_scopes=${H}`:""}`}async function IZ($,Z){try{return await Z()}catch(J){v8($,J)}}function v8($,Z){throw Error(IH($,Z))}var gH=O(()=>{r()});var J0={};S$(J0,{writeAliveMarker:()=>QJ,urgentApp:()=>m1,uploadImageKey:()=>BJ,uploadAndSend:()=>T9,updateCard:()=>r2,unbindSessionChat:()=>h8,tempProjectName:()=>v$,tempChatName:()=>$J,setPendingConversationLaunchChecked:()=>H1,sendTextRaw:()=>w,sendText:()=>E,sendImage:()=>d8,sendFile:()=>Hz,sendCard:()=>u,sanitizeSessionName:()=>jJ,resolveProjectDir:()=>n2,replaceTurnAnchors:()=>l0,registerTempSessionLease:()=>nZ,refreshChatList:()=>N9,readAliveMarker:()=>VJ,provisionProject:()=>_J,projectProfileForDirectory:()=>U9,projectProfile:()=>oF,preferredChatForSession:()=>G0,loadTempSessionLeases:()=>iZ,loadSessionTurnsMap:()=>rZ,loadSessionResumeMap:()=>sZ,loadSessionModelMap:()=>ZJ,loadSessionChatMap:()=>oZ,listNormalChatIdsByName:()=>p8,isOpenAIChatGPTAuthenticated:()=>E9,hasTempSessionLease:()=>aZ,getTurnAnchors:()=>o2,getTenantToken:()=>E$,getSessionResumeRef:()=>X1,getSessionModelSelection:()=>JJ,getSessionBranchBase:()=>s2,getPendingConversationLaunch:()=>t2,getChatTailMessageId:()=>KJ,formatFeishuApiError:()=>IH,findNormalChatIdByName:()=>c8,fetchChatOwnerOpenId:()=>vZ,fetchChatName:()=>WJ,ensureChatForSession:()=>XJ,downloadAttachment:()=>R9,disbandChatForSessionExact:()=>GJ,disbandChatForSession:()=>zJ,deleteTasklistByGuid:()=>hZ,deleteReaction:()=>k0,createTempChatForSession:()=>HJ,createTasklistWithOwner:()=>fZ,client:()=>X0,clearSessionResumeChecked:()=>a2,clearSessionConversationState:()=>YJ,chatNameCache:()=>W0,chatIdForSession:()=>m8,bindSessionToChat:()=>i2,bindSessionResumeChecked:()=>O9,bindSessionModelChecked:()=>z1,bindSessionModel:()=>ZD,appendTurnAnchorChecked:()=>eZ,addReaction:()=>d0,PROJECTS_ROOT:()=>dZ,MAX_UPLOAD_BYTES:()=>l8});import*as iH from"@larksuiteoapi/node-sdk";import{execSync as dF}from"node:child_process";import{randomUUID as lZ}from"node:crypto";import{mkdirSync as mZ,readFileSync as g1,statSync as nH,writeFileSync as aH}from"node:fs";import{readFile as iF}from"node:fs/promises";import{homedir as mH}from"node:os";import{basename as d2,extname as nF,isAbsolute as oH,join as pZ}from"node:path";import{sync as aF}from"cross-spawn";function cZ(){let $={};for(let[Z,J]of u0)$[Z]=J;o(r7,$)}function iZ(){u0.clear();try{let $=JSON.parse(g1(r7,"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"||!v$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}u0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}B(`feishu: loaded ${u0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function nZ($,Z){if(!v$($))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{cZ()}catch(Q){if(J)u0.set(Z,J);else u0.delete(Z);throw Q}}function aZ($,Z){let J=u0.get(Z);return J?.sessionName===$&&J.chatId===Z}function oF($){return v.projects[$]}function n2($){return wZ($,dZ,v.projects)}function U9($){return hH($,dZ,v.projects)}function A9($,Z={}){return z0($,{...Z,signal:Z.signal??AbortSignal.timeout(rH)})}async function eH($,Z,J){let Y=Z.signal??AbortSignal.timeout(rH);try{return await p2(await A9($,{...Z,signal:Y}),J)}catch(Q){if(Y.aborted&&Y.reason?.name==="TimeoutError")throw Y.reason;throw Q}}async function E$(){if(f8&&Date.now()<pH)return f8;return gZ??=(async()=>{let $=await eH("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:tH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return f8=$.tenant_access_token,pH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,f8})().finally(()=>{gZ=null}),gZ}function oZ(){try{let $=JSON.parse(g1(a7,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")G0.set(Z,J);B(`feishu: loaded ${G0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function $z(){try{uZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function uZ(){let $={};for(let[Z,J]of G0)$[Z]=J;o(a7,$)}function i2($,Z){if(G0.get($)===Z)return;let J=G0.get($);G0.set($,Z),$z(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function h8($){let Z=G0.get($);if(!Z)return;G0.delete($),$z(),B(`feishu: unbound session "${$}" from ${Z}`)}function D9($,Z){let J=P0.get($)??{};J[Z.provider]=Z,P0.set($,J)}function cH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=M$(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"||!oH(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function uH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!M$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!oH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function sF($,Z,J){if(typeof $!=="string")return uH($);if(!Z)throw Error("cannot bind a conversation without a provider");return uH({provider:Z,sessionId:$,cwd:J??null})}function sZ(){try{let $=JSON.parse(g1(o7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");P0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){D9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=cH(Y);if(Q){D9(Z,Q);continue}for(let V of D5){let X=Y[V];if(typeof X==="string"&&X.trim()){D9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let H=cH(X,V);if(H)D9(Z,H)}}B(`feishu: loaded ${P0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function I8(){let $={};for(let[Z,J]of P0){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}o(o7,$)}function O9($,Z,J,Y){let Q=sF(Z,J,Y),V=P0.get($),X=V?{...V}:void 0,H=V?.[Q.provider];if(H?.sessionId===Q.sessionId&&H.cwd===Q.cwd)return;D9($,Q);try{I8()}catch(z){if(X)P0.set($,X);else P0.delete($);throw z}}function X1($,Z="codex"){let J=P0.get($)?.[Z];return J?{...J}:null}function a2($,Z){let J=P0.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)P0.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)P0.delete($);else P0.set($,Q)}try{I8()}catch(Q){throw P0.set($,Y),Q}}function Zz($){if(!$||typeof $!=="object")return null;let Z=$;if(!M$(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 Jz($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=Zz(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 Yz($){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=Zz(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=Jz(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{L0(Y,J.provider)}catch{return null}return Y}function tF($){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 rF($,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=Jz(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let V=typeof J.uuid==="string"?J.uuid.trim():"",X=typeof J.sid==="string"?J.sid.trim():"";if(!V||!X)return null;Q={provider:"claude",kind:"assistant-message",id:V,source:{provider:"claude",sessionId:X,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:tF(J.writes)}}function eF($){if(!$||typeof $!=="object")return null;let Z=$,J=Yz(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 tZ($){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 rZ(){try{let $=JSON.parse(g1(s7,"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,X,H=null;if(Array.isArray(Q))V=Q,X=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let K=Q;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(V=K.anchors,K.base===null)X=null;else{let _=Yz(K.base);if(!_){J++;continue}X=_}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let _=eF(K.pendingLaunch);if(!_){J++;continue}H=_}}else{J++;continue}let z=P0.get(Y),G=z?.claude!==void 0&&z.codex===void 0?"claude":null,W=[];for(let K of V){let _=rF(K,G);if(_)W.push(_);else J++}if(W.length||X!==null||H)e.set(Y,{base:X,anchors:W,...H?{pendingLaunch:H}:{}}),Z+=W.length}if(B(`feishu: loaded ${Z} turn anchors across ${e.size} sessions`),J>0)B(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function M9(){let $={};for(let[Z,J]of e)$[Z]=J;o(s7,$)}function eZ($,Z){let J=e.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>lH){let V=Y.splice(0,Y.length-lH),X=V[V.length-1].checkpoint;Q={kind:"fork",source:X.source,through:X}}e.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{M9()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function o2($){return e.get($)?.anchors??[]}function s2($){return e.get($)?.base??null}function t2($){let Z=e.get($)?.pendingLaunch;return Z?tZ(Z):null}function H1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");L0(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:tZ(Z)}:{}});try{M9()}catch(V){if(J)e.set($,J);else e.delete($);throw V}}function l0($,Z,J,Y){let Q=e.get($),V=Y===void 0?Q?.pendingLaunch:Y??void 0,X=V?tZ(V):void 0;if(Z.length===0&&J===null&&!X)e.delete($);else e.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{M9()}catch(H){if(Q)e.set($,Q);else e.delete($);throw H}}function v$($){return dH.test($)?$.replace(dH,""):null}function $J($,Z=[]){let J=new Date,Y=(H)=>String(H).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,V=new Set([...W0.values(),...e.keys(),...Z]),X=`${$}*${Q}`;for(let H=2;V.has(X);H++)X=`${$}*${Q}-${H}`;return X}function ZJ(){try{let $=JSON.parse(g1(t7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){b0.set(Z,{provider:F2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,V=M$(Q)?Q:typeof Y==="string"&&Y.trim()?F2(Y):"claude",X=typeof Y==="string"&&Y.trim()?Y:null;if(V==="claude"&&!X)continue;let{effort:H,tokenSourceId:z}=J,G=typeof z==="string"&&z.trim()?z.trim():null,W=V==="dsh"?_0(H)?H:null:V==="claude"?F0(H)?H:null:t0(H)?H:null;b0.set(Z,{provider:V,model:X,effort:W,...G?{tokenSourceId:G}:{}})}B(`feishu: loaded ${b0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-model-map failed: ${$?.message??$}`)}}function $D(){try{g8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function g8(){let $={};for(let[Z,J]of b0)$[Z]=J;o(t7,$)}function ZD($,Z,J,Y,Q){let V=b0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Y&&(V.tokenSourceId??null)===(Q??null))return;b0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),$D()}function z1($,Z,J,Y,Q){let V=b0.get($),X={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;b0.set($,X);try{g8()}catch(H){if(V)b0.set($,V);else b0.delete($);throw H}}function JJ($){let Z=b0.get($);if(Z)return Z;let J=v$($);return J?b0.get(J)??null:null}function YJ($){let Z=G0.get($),J=P0.get($),Y=b0.get($),Q=e.get($),V=[...u0.entries()].filter(([,X])=>X.sessionName===$);G0.delete($),P0.delete($),b0.delete($),e.delete($);for(let[X]of V)u0.delete(X);try{uZ(),I8(),g8(),M9(),cZ()}catch(X){if(Z)G0.set($,Z);if(J)P0.set($,J);if(Y)b0.set($,Y);if(Q)e.set($,Q);for(let[z,G]of V)u0.set(z,G);let H=[X];for(let z of[uZ,I8,g8,M9,cZ])try{z()}catch(G){H.push(G)}throw H.length===1?H[0]:AggregateError(H,`failed to clear and restore conversation state for ${$}`)}}function QJ($){o($5,$)}function VJ(){let $;try{$=g1($5,"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 m8($){let Z=G0.get($);if(Z){let Y=W0.get(Z);if(Y&&Y!==$)B(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of W0)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)B(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function N9(){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)W0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${W0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function p8(){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;W0.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 c8($){let Z=G0.get($);if(Z&&W0.get(Z)===$){let V=await Qz(Z);if(V.name===$&&Vz(V.status))return Z;W0.delete(Z),h8($)}let Y=(await p8()).get($)??[];if(Y.length===0)return null;let Q=G0.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 XJ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await c8($);if(J){let V=await JD(J,Z);return i2($,J),{chatId:J,created:!1,joined:V}}let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:lZ()},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 W0.set(Q,$),i2($,Q),{chatId:Q,created:!0,joined:!0}}async function HJ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await c8($))throw Error(`temporary group name already exists: ${$}`);let Y=await X0.im.chat.create({params:{user_id_type:"open_id",uuid:lZ()},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 W0.set(Q,$),i2($,Q),{chatId:Q,created:!0,joined:!0}}async function zJ($){let Z=await c8($);if(!Z)return h8($),{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(W0.delete(Z),G0.get($)===Z)h8($);return{chatId:Z,disbanded:!0}}async function GJ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await Qz(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!Vz(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 W0.delete(Z),{chatId:Z,disbanded:!0}}async function JD($,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 WJ($){try{let Z=await E$(),Y=await(await A9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return B(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return W0.set($,Q),B(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return B(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return B(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function u8($,Z,J,Y){let Q=lZ();try{return await f1(`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 R$(`send${$} code=${V?.code??"MISS"} msg=${V?.msg??"MISS"}`,void 0,V?.code);let X=V?.data?.message_id;if(typeof X!=="string"||!X.trim())throw Error(`send${$} message_id MISS`);return X})}catch{return null}}async function Qz($){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 Vz($){return $===null||$==="normal"}async function E($,Z){return B$($,()=>u8("Text",$,"text",JSON.stringify({text:Z})))}async function u($,Z){return B$($,()=>u8("Card",$,"interactive",JSON.stringify(o$(Z))))}async function KJ($){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 r2($,Z){let J=await X0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(o$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function w($,Z){return B$($,()=>YD($,Z))}async function YD($,Z){try{let J=await E$(),Q=await(await A9("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 B(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function d0($,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 B(`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){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function m1($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await E$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await A9(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(V?.code!==0){B(`feishu: urgentApp ${$} code=${V?.code} msg=${V?.msg}`);return}let X=V.data?.invalid_user_id_list??[],H=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${H}${X.length?` invalid=${X.length}`:""}`)}catch(Q){B(`feishu: urgentApp ${$} failed: ${Q}`)}}async function R9($,Z,J,Y){try{let Q=await E$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await A9(V,{headers:{Authorization:`Bearer ${Q}`}});if(!X.ok){B(`feishu: download ${J} HTTP ${X.status}: ${(await X.text()).slice(0,200)}`);return}let H=Buffer.from(await X.arrayBuffer());mZ(Z5,{recursive:!0});let z=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=pZ(Z5,`${Date.now()}-${z}`);return aH(G,H),B(`feishu: downloaded ${J} ${G} (${H.length}B)`),G}catch(Q){B(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function VD($){return QD.has(nF($).toLowerCase())}async function Xz($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Y;return f1(`${J} ${$}`,async()=>{if(Y??=new Blob([Uint8Array.from(await iF($))]),Y.size>l8)throw Error(`${d2($)} 超过 30 MB`);let Q=await E$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",d2($));V.append(Z,Y,d2($));let H=(await eH(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Q}`},body:V},J)).data?.[`${Z}_key`];if(typeof H!=="string"||!H.trim())throw Error(`${J} ${Z}_key MISS`);return H})}async function BJ($){try{let Z=nH($);if(!Z.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>l8)return B(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return B(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}try{return await Xz($,"image")}catch{return null}}async function d8($,Z){return B$($,()=>u8("Image",$,"image",JSON.stringify({image_key:Z})))}async function Hz($,Z){return B$($,()=>u8("File",$,"file",JSON.stringify({file_key:Z})))}async function T9($,Z){try{let Q=nH(Z);if(!Q.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await E($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Q.size>l8)return B(`feishu: uploadAndSend oversize — ${Z} (${Q.size}B)`),await E($,`❌ 出站文件: ${d2(Z)} 超过 30 MB (${(Q.size/1024/1024).toFixed(1)} MB)`),!1}catch(Q){return B(`feishu: uploadAndSend stat failed — ${Z}: ${Q}`),await E($,`❌ 出站文件: 无法读取 ${Z} (${Q})`),!1}let J=VD(Z)?"image":"file",Y=J==="image"?"出站图片":"出站文件";try{let Q=await Xz(Z,J),V=await(J==="image"?d8($,Q):Hz($,Q));if(!V)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await E($,`❌ ${Y}发送失败: ${d2(Z)}(上传已完成)`),!1;return B(`feishu: uploadAndSend ${Z} delivered msg=${V}`),!0}catch(Q){return B(`feishu: uploadAndSend ${Z} failed: ${Q}`),await E($,`❌ ${Y}上传失败: ${d2(Z)} — ${Q}`),!1}}function _J($){mZ($,{recursive:!0}),B(`feishu: provisioned ${$}`);let Z=pZ(mH(),".codex","config.toml");try{mZ(pZ(mH(),".codex"),{recursive:!0});let J="";try{J=g1(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
213
+ ${G}`)}return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1}}function gZ($){if(!l1($))throw Error(`project directory does not exist: ${$}`);let Z=N0($,["rev-parse","--show-toplevel"]).trim();if(hZ(Z)!==hZ($))throw Error(`${$} is not the git repository root (${Z})`)}function dH($,Z){let J=N0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function rP($,Z,J){let Q=eP($);if(!Q?.startsWith(n2))return null;let Y=Q.slice(n2.length);if(!d1(Y))throw Error(`invalid worktree branch "${Q}"`);let V=o2(Z,J,Y);if(m8($)!==m8(V))return null;let X=ZD($,$D(Y));return X?{path:X,slug:Y}:null}function eP($){if(!l1($))return null;try{return N0($,["branch","--show-current"]).trim()||null}catch(Z){if(QD(Z))return null;throw Z}}function $D($){return $.split("-",1)[0]??$}function ZD($,Z){let J=`agents.${Z}.md`,Q=nP($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?gH($,Q[0]):null}function JD($,Z){try{return N0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function iH($,Z,J){let Q=N0($,["rev-parse",Z]).trim(),Y=N0($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(IH($,Z,"HEAD"))return"merged";if(IH($,"HEAD",Z))return"active";return"stale"}function IH($,Z,J){try{return N0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function mZ($){let Z=new Map,J=N0($,["worktree","list","--porcelain"]),Q="";for(let Y of J.split(`
214
+ `)){if(Y.startsWith("worktree ")){Q=Y.slice(9);continue}if(Y.startsWith("branch refs/heads/")&&Q)Z.set(Y.slice(18),Q)}return Z}function N0($,Z){try{return iP("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(pZ(J))}}function pZ($){if($&&typeof $==="object"){let Z=$,J=Z.stderr?String(Z.stderr).trim():"";if(J)return J;if(Z.message)return Z.message}return String($)}function QD($){return/not a git repository/i.test(pZ($))}var n2="work/",tP,g8;var cZ=O(()=>{tP=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,g8=new Map});import{lstatSync as VD,realpathSync as XD,statSync as HD}from"node:fs";import{basename as zD,dirname as nH,isAbsolute as WD,join as aH,resolve as GD}from"node:path";function KD($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function uZ($,Z,J){let Q=KD($),Y=c8(Q),V=J[Y]?.cwd?.trim()||aH(Z,Y);if(Q===Y)return V;return o2(V,Y,Q.slice(Y.length+1,-1))}function C$($){if(!WD($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=oH(GD($));return process.platform==="win32"?Z.toLowerCase():Z}function oH($){try{let Z=XD($);if(!HD(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||nH($)===$)throw Z;try{if(VD($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return aH(oH(nH($)),zD($))}}function sH($,Z,J){let Q=C$($),Y,V=new Map;for(let[X,H]of Object.entries(J)){if(C$(uZ(X,Z,J))!==Q)continue;Y??={cwd:$};for(let z of["settingSources","strictMcp","tools","loadProjectMcp"]){let W=H[z];if(W===void 0)continue;if(Y[z]!==void 0&&Y[z]!==W)throw Error(`同一工作目录的项目配置冲突: ${V.get(z)} / ${X}, ${z} (${$})`);Object.assign(Y,{[z]:W}),V.set(z,X)}}return Y}var u8=O(()=>{cZ()});async function lZ($){let Z=await nZ("feishu chat.get",()=>z0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)l8("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 dZ($,Z){let J=await nZ("feishu tasklist.create",()=>z0.task.v2.tasklist.create({params:{user_id_type:"open_id"},data:{name:$,members:[{id:Z,type:"user",role:"editor"}]}}));if(J.code&&J.code!==0)l8("feishu tasklist.create",J);let Q=J.data?.tasklist,Y=Q?.guid;if(!Y)throw Error("feishu tasklist.create returned no guid");return{guid:Y,name:Q?.name||$,url:Q?.url??"",createdAt:Q?.created_at}}async function iZ($){let Z=await nZ("feishu tasklist.delete",()=>z0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)l8("feishu tasklist.delete",Z)}function tH($,Z){let J=Z&&typeof Z==="object"?Z:{},Q=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Y=Q.code??J.code,V=Q.msg??Q.message??J.msg??J.message??"unknown error",X=Q.error?.permission_violations??Q.permission_violations??J.error?.permission_violations,H=Array.isArray(X)?X.map((z)=>z?.scope??z?.subject??z?.name??z).filter(Boolean).join(", "):"";return`${$} failed code=${Y??"unknown"} msg=${V}${H?` missing_scopes=${H}`:""}`}async function nZ($,Z){try{return await Z()}catch(J){l8($,J)}}function l8($,Z){throw Error(tH($,Z))}var rH=O(()=>{r()});var J0={};v$(J0,{writeAliveMarker:()=>_J,urgentApp:()=>n1,uploadImageKey:()=>MJ,uploadAndSend:()=>w9,updateCard:()=>Q4,unbindSessionChat:()=>i8,tempProjectName:()=>c$,tempChatName:()=>WJ,setPendingConversationLaunchChecked:()=>q1,sendTextRaw:()=>I,sendText:()=>S,sendImage:()=>$5,sendFile:()=>Uz,sendCard:()=>u,sanitizeSessionName:()=>OJ,resolveProjectDir:()=>r2,replaceTurnAnchors:()=>s0,registerTempSessionLease:()=>JJ,refreshChatList:()=>b9,readAliveMarker:()=>jJ,provisionProject:()=>AJ,projectProfileForDirectory:()=>x9,projectProfile:()=>qD,preferredChatForSession:()=>K0,loadTempSessionLeases:()=>ZJ,loadSessionTurnsMap:()=>HJ,loadSessionResumeMap:()=>VJ,loadSessionModelMap:()=>GJ,loadSessionChatMap:()=>YJ,listNormalChatIdsByName:()=>s8,isOpenAIChatGPTAuthenticated:()=>y9,hasTempSessionLease:()=>QJ,getTurnAnchors:()=>$4,getTenantToken:()=>b$,getSessionResumeRef:()=>L1,getSessionModelSelection:()=>KJ,getSessionBranchBase:()=>Z4,getPendingConversationLaunch:()=>J4,getChatTailMessageId:()=>UJ,formatFeishuApiError:()=>tH,findNormalChatIdByName:()=>t8,fetchChatOwnerOpenId:()=>lZ,fetchChatName:()=>DJ,ensureChatForSession:()=>LJ,downloadAttachment:()=>k9,disbandChatForSessionExact:()=>PJ,disbandChatForSession:()=>FJ,deleteTasklistByGuid:()=>iZ,deleteReaction:()=>k0,createTempChatForSession:()=>qJ,createTasklistWithOwner:()=>dZ,client:()=>z0,clearSessionResumeChecked:()=>e2,clearSessionConversationState:()=>BJ,chatNameCache:()=>B0,chatIdForSession:()=>o8,bindSessionToChat:()=>t2,bindSessionResumeChecked:()=>C9,bindSessionModelChecked:()=>F1,bindSessionModel:()=>AD,appendTurnAnchorChecked:()=>zJ,addReaction:()=>t0,PROJECTS_ROOT:()=>$J,MAX_UPLOAD_BYTES:()=>e8});import*as Vz from"@larksuiteoapi/node-sdk";import{execSync as BD}from"node:child_process";import{randomUUID as eZ}from"node:crypto";import{mkdirSync as oZ,readFileSync as i1,statSync as Xz,writeFileSync as Hz}from"node:fs";import{readFile as _D}from"node:fs/promises";import{homedir as eH}from"node:os";import{basename as s2,extname as jD,isAbsolute as zz,join as sZ}from"node:path";import{sync as LD}from"cross-spawn";function tZ(){let $={};for(let[Z,J]of o0)$[Z]=J;o(W7,$)}function ZJ(){o0.clear();try{let $=JSON.parse(i1(W7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Q=J;if(typeof Z!=="string"||!Z||Q.chatId!==Z||typeof Q.sessionName!=="string"||!c$(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}o0.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}B(`feishu: loaded ${o0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function JJ($,Z){if(!c$($))throw Error(`refusing to lease non-temporary session name "${$}"`);if(!Z)throw Error("cannot lease a temporary session without chat_id");for(let Y of o0.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=o0.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};o0.set(Z,Q);try{tZ()}catch(Y){if(J)o0.set(Z,J);else o0.delete(Z);throw Y}}function QJ($,Z){let J=o0.get(Z);return J?.sessionName===$&&J.chatId===Z}function qD($){return g.projects[$]}function r2($){return uZ($,$J,g.projects)}function x9($){return sH($,$J,g.projects)}function S9($,Z={}){return X0($,{...Z,signal:Z.signal??AbortSignal.timeout(Kz)})}async function Bz($,Z,J){let Q=Z.signal??AbortSignal.timeout(Kz);try{return await i2(await S9($,{...Z,signal:Q}),J)}catch(Y){if(Q.aborted&&Q.reason?.name==="TimeoutError")throw Q.reason;throw Y}}async function b$(){if(d8&&Date.now()<$z)return d8;return aZ??=(async()=>{let $=await Bz("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:Wz,app_secret:Gz})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return d8=$.tenant_access_token,$z=Date.now()+Math.max(0,($.expire??7200)-60)*1000,d8})().finally(()=>{aZ=null}),aZ}function YJ(){try{let $=JSON.parse(i1(V7,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")K0.set(Z,J);B(`feishu: loaded ${K0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function _z(){try{rZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function rZ(){let $={};for(let[Z,J]of K0)$[Z]=J;o(V7,$)}function t2($,Z){if(K0.get($)===Z)return;let J=K0.get($);K0.set($,Z),_z(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function i8($){let Z=K0.get($);if(!Z)return;K0.delete($),_z(),B(`feishu: unbound session "${$}" from ${Z}`)}function T9($,Z){let J=P0.get($)??{};J[Z.provider]=Z,P0.set($,J)}function Zz($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=O$(J.provider)?J.provider:Z??null;if(!Q||Z&&Q!==Z)return null;let Y=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Y)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Q,sessionId:Y,cwd:null};if(typeof J.cwd!=="string"||!zz(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function Jz($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!O$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!zz($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function FD($,Z,J){if(typeof $!=="string")return Jz($);if(!Z)throw Error("cannot bind a conversation without a provider");return Jz({provider:Z,sessionId:$,cwd:J??null})}function VJ(){try{let $=JSON.parse(i1(X7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");P0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){T9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=Zz(Q);if(Y){T9(Z,Y);continue}for(let V of C7){let X=Q[V];if(typeof X==="string"&&X.trim()){T9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let H=Zz(X,V);if(H)T9(Z,H)}}B(`feishu: loaded ${P0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function n8(){let $={};for(let[Z,J]of P0){let Q={};if(J.codex)Q.codex={...J.codex};if(J.claude)Q.claude={...J.claude};if(J.dsh)Q.dsh={...J.dsh};$[Z]=Q}o(X7,$)}function C9($,Z,J,Q){let Y=FD(Z,J,Q),V=P0.get($),X=V?{...V}:void 0,H=V?.[Y.provider];if(H?.sessionId===Y.sessionId&&H.cwd===Y.cwd)return;T9($,Y);try{n8()}catch(z){if(X)P0.set($,X);else P0.delete($);throw z}}function L1($,Z="codex"){let J=P0.get($)?.[Z];return J?{...J}:null}function e2($,Z){let J=P0.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)P0.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)P0.delete($);else P0.set($,Y)}try{n8()}catch(Y){throw P0.set($,Q),Y}}function jz($){if(!$||typeof $!=="object")return null;let Z=$;if(!O$(Z.provider))return null;let J=typeof Z.sessionId==="string"?Z.sessionId.trim():"";if(!J)return null;let Q;if(Z.cwd===void 0||Z.cwd===null)Q=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Q=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Q}}function Lz($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=jz(J),Y=typeof Z.id==="string"?Z.id.trim():"";if(!Y||!Q)return null;if(Z.provider==="dsh"&&Z.kind==="event"&&Q.provider==="dsh"&&/^\d+$/.test(Y)&&Number.isSafeInteger(Number(Y)))return{provider:"dsh",kind:"event",id:Y,source:{...Q,provider:"dsh"}};if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Q.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Y,source:{...Q,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Q.provider==="codex")return{provider:"codex",kind:"turn",id:Y,source:{...Q,provider:"codex"}};return null}function qz($){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=jz(Z.source);if(!J)return null;let Q=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Y=Lz(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{F0(Q,J.provider)}catch{return null}return Q}function PD($){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 DD($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Q=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Y=Lz(J.checkpoint);if(Q&&!Y)return null;if(!Y){if(Z!=="claude")return null;let V=typeof J.uuid==="string"?J.uuid.trim():"",X=typeof J.sid==="string"?J.sid.trim():"";if(!V||!X)return null;Y={provider:"claude",kind:"assistant-message",id:V,source:{provider:"claude",sessionId:X,cwd:null}}}return{checkpoint:Y,preview:String(J.preview??""),ts:J.ts,writes:PD(J.writes)}}function UD($){if(!$||typeof $!=="object")return null;let Z=$,J=qz(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Q=Z.previousSessionId,Y=Q===null?null:typeof Q==="string"&&Q.trim()?Q.trim():void 0;if(Y===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Y}}function XJ($){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 HJ(){try{let $=JSON.parse(i1(H7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");$0.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let V,X,H=null;if(Array.isArray(Y))V=Y,X=null;else if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let K=Y;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(V=K.anchors,K.base===null)X=null;else{let _=qz(K.base);if(!_){J++;continue}X=_}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let _=UD(K.pendingLaunch);if(!_){J++;continue}H=_}}else{J++;continue}let z=P0.get(Q),W=z?.claude!==void 0&&z.codex===void 0?"claude":null,G=[];for(let K of V){let _=DD(K,W);if(_)G.push(_);else J++}if(G.length||X!==null||H)$0.set(Q,{base:X,anchors:G,...H?{pendingLaunch:H}:{}}),Z+=G.length}if(B(`feishu: loaded ${Z} turn anchors across ${$0.size} sessions`),J>0)B(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function E9(){let $={};for(let[Z,J]of $0)$[Z]=J;o(H7,$)}function zJ($,Z){let J=$0.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>Qz){let V=Q.splice(0,Q.length-Qz),X=V[V.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}$0.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{E9()}catch(V){if(J)$0.set($,J);else $0.delete($);throw V}}function $4($){return $0.get($)?.anchors??[]}function Z4($){return $0.get($)?.base??null}function J4($){let Z=$0.get($)?.pendingLaunch;return Z?XJ(Z):null}function q1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");F0(Z.launch,"claude",Z.launch.source.cwd)}let J=$0.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)$0.delete($);else $0.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:XJ(Z)}:{}});try{E9()}catch(V){if(J)$0.set($,J);else $0.delete($);throw V}}function s0($,Z,J,Q){let Y=$0.get($),V=Q===void 0?Y?.pendingLaunch:Q??void 0,X=V?XJ(V):void 0;if(Z.length===0&&J===null&&!X)$0.delete($);else $0.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{E9()}catch(H){if(Y)$0.set($,Y);else $0.delete($);throw H}}function c$($){return Yz.test($)?$.replace(Yz,""):null}function WJ($,Z=[]){let J=new Date,Q=(H)=>String(H).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,V=new Set([...B0.values(),...$0.keys(),...Z]),X=`${$}*${Y}`;for(let H=2;V.has(X);H++)X=`${$}*${Y}-${H}`;return X}function GJ(){try{let $=JSON.parse(i1(z7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){b0.set(Z,{provider:R2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,V=O$(Y)?Y:typeof Q==="string"&&Q.trim()?R2(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(V==="claude"&&!X)continue;let{effort:H,tokenSourceId:z}=J,W=typeof z==="string"&&z.trim()?z.trim():null,G=V==="dsh"?q0(H)?H:null:V==="claude"?D0(H)?H:null:Z$(H)?H:null;b0.set(Z,{provider:V,model:X,effort:G,...W?{tokenSourceId:W}:{}})}B(`feishu: loaded ${b0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-model-map failed: ${$?.message??$}`)}}function MD(){try{a8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function a8(){let $={};for(let[Z,J]of b0)$[Z]=J;o(z7,$)}function AD($,Z,J,Q,Y){let V=b0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Q&&(V.tokenSourceId??null)===(Y??null))return;b0.set($,{provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}}),MD()}function F1($,Z,J,Q,Y){let V=b0.get($),X={provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}};if(V?.provider===Z&&V.model===J&&V.effort===Q&&(V.tokenSourceId??null)===(Y??null))return;b0.set($,X);try{a8()}catch(H){if(V)b0.set($,V);else b0.delete($);throw H}}function KJ($){let Z=b0.get($);if(Z)return Z;let J=c$($);return J?b0.get(J)??null:null}function BJ($){let Z=K0.get($),J=P0.get($),Q=b0.get($),Y=$0.get($),V=[...o0.entries()].filter(([,X])=>X.sessionName===$);K0.delete($),P0.delete($),b0.delete($),$0.delete($);for(let[X]of V)o0.delete(X);try{rZ(),n8(),a8(),E9(),tZ()}catch(X){if(Z)K0.set($,Z);if(J)P0.set($,J);if(Q)b0.set($,Q);if(Y)$0.set($,Y);for(let[z,W]of V)o0.set(z,W);let H=[X];for(let z of[rZ,n8,a8,E9,tZ])try{z()}catch(W){H.push(W)}throw H.length===1?H[0]:AggregateError(H,`failed to clear and restore conversation state for ${$}`)}}function _J($){o(K7,$)}function jJ(){let $;try{$=i1(K7,"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 o8($){let Z=K0.get($);if(Z){let Q=B0.get(Z);if(Q&&Q!==$)B(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Q}", using persisted binding`);return Z}let J=[];for(let[Q,Y]of B0)if(Y===$)J.push(Q);if(J.length===1)return J[0];if(J.length>1)B(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function b9(){try{let $;do{let Z=await z0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)B0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${B0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function s8(){let $=new Map,Z;do{let J=await z0.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Q of J.data?.items??[]){if(!Q.chat_id||!Q.name)continue;if(Q.chat_status&&Q.chat_status!=="normal")continue;B0.set(Q.chat_id,Q.name);let Y=$.get(Q.name)??[];Y.push(Q.chat_id),$.set(Q.name,Y)}Z=J.data?.page_token}while(Z);return $}async function t8($){let Z=K0.get($);if(Z&&B0.get(Z)===$){let V=await Fz(Z);if(V.name===$&&Pz(V.status))return Z;B0.delete(Z),i8($)}let Q=(await s8()).get($)??[];if(Q.length===0)return null;let Y=K0.get($);if(Y&&Q.includes(Y))return Y;if(Q.length===1)return Q[0];throw Error(`multiple Feishu groups named "${$}": ${Q.join(", ")}`)}async function LJ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await t8($);if(J){let V=await OD(J,Z);return t2($,J),{chatId:J,created:!1,joined:V}}let Q=await z0.im.chat.create({params:{user_id_type:"open_id",uuid:eZ()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return B0.set(Y,$),t2($,Y),{chatId:Y,created:!0,joined:!0}}async function qJ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await t8($))throw Error(`temporary group name already exists: ${$}`);let Q=await z0.im.chat.create({params:{user_id_type:"open_id",uuid:eZ()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.create failed code=${Q.code} msg=${Q.msg}`);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return B0.set(Y,$),t2($,Y),{chatId:Y,created:!0,joined:!0}}async function FJ($){let Z=await t8($);if(!Z)return i8($),{chatId:null,disbanded:!1};let J=await z0.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw Error(`feishu chat.delete failed code=${J.code} msg=${J.msg}`);if(B0.delete(Z),K0.get($)===Z)i8($);return{chatId:Z,disbanded:!0}}async function PJ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await Fz(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!Pz(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await z0.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw Error(`feishu chat.delete failed code=${Q.code} msg=${Q.msg}`);return B0.delete(Z),{chatId:Z,disbanded:!0}}async function OD($,Z){let J;do{let Y=await z0.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.get failed code=${Y.code} msg=${Y.msg}`);for(let V of Y.data?.items??[])if(V.member_id===Z)return!1;J=Y.data?.page_token}while(J);let Q=await z0.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.create failed code=${Q.code} msg=${Q.msg}`);return!0}async function DJ($){try{let Z=await b$(),Q=await(await S9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Q?.code!==0)return B(`feishu: fetchChatName ${$} code=${Q?.code} msg=${Q?.msg}`),null;let Y=Q.data?.name;if(typeof Y==="string"&&Y)return B0.set($,Y),B(`feishu: fetchChatName ${$} → "${Y}" (point lookup)`),Y;return B(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return B(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function r8($,Z,J,Q){let Y=eZ();try{return await u1(`send${$} chat=${Z}`,async()=>{let V=await z0.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Q,uuid:Y}});if(V?.code!==0)throw new S$(`send${$} code=${V?.code??"MISS"} msg=${V?.msg??"MISS"}`,void 0,V?.code);let X=V?.data?.message_id;if(typeof X!=="string"||!X.trim())throw Error(`send${$} message_id MISS`);return X})}catch{return null}}async function Fz($){let Z=await z0.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw Error(`feishu chat.get failed code=${Z.code} msg=${Z.msg}`);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function Pz($){return $===null||$==="normal"}async function S($,Z){return j$($,()=>r8("Text",$,"text",JSON.stringify({text:Z})))}async function u($,Z){return j$($,()=>r8("Card",$,"interactive",JSON.stringify(Q1(Z))))}async function UJ($){let Z=await z0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw Error(`feishu message.list failed code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);if(!Array.isArray(Z.data?.items))throw Error("feishu message.list items MISS");if(Z.data.items.length===0)return null;let J=Z.data.items[0]?.message_id;if(typeof J!=="string"||!J.trim())throw Error("feishu message.list message_id MISS");return J}async function Q4($,Z){let J=await z0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(Q1(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function I($,Z){return j$($,()=>ND($,Z))}async function ND($,Z){try{let J=await b$(),Y=await(await S9("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(Y?.code!==0)return B(`feishu: sendTextRaw rejected chat=${$} code=${Y?.code} msg=${Y?.msg}`),null;return Y.data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function t0($,Z){if(!$)return null;try{return(await z0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return B(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function k0($,Z){if(!$||!Z)return;try{await z0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function n1($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await b$(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let V=await(await S9(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(V?.code!==0){B(`feishu: urgentApp ${$} code=${V?.code} msg=${V?.msg}`);return}let X=V.data?.invalid_user_id_list??[],H=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${H}${X.length?` invalid=${X.length}`:""}`)}catch(Y){B(`feishu: urgentApp ${$} failed: ${Y}`)}}async function k9($,Z,J,Q){try{let Y=await b$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await S9(V,{headers:{Authorization:`Bearer ${Y}`}});if(!X.ok){B(`feishu: download ${J} HTTP ${X.status}: ${(await X.text()).slice(0,200)}`);return}let H=Buffer.from(await X.arrayBuffer());oZ(B7,{recursive:!0});let z=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,W=sZ(B7,`${Date.now()}-${z}`);return Hz(W,H),B(`feishu: downloaded ${J} ${W} (${H.length}B)`),W}catch(Y){B(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function TD($){return RD.has(jD($).toLowerCase())}async function Dz($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Q;return u1(`${J} ${$}`,async()=>{if(Q??=new Blob([Uint8Array.from(await _D($))]),Q.size>e8)throw Error(`${s2($)} 超过 30 MB`);let Y=await b$(),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,Q,s2($));let H=(await Bz(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:V},J)).data?.[`${Z}_key`];if(typeof H!=="string"||!H.trim())throw Error(`${J} ${Z}_key MISS`);return H})}async function MJ($){try{let Z=Xz($);if(!Z.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>e8)return B(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return B(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}try{return await Dz($,"image")}catch{return null}}async function $5($,Z){return j$($,()=>r8("Image",$,"image",JSON.stringify({image_key:Z})))}async function Uz($,Z){return j$($,()=>r8("File",$,"file",JSON.stringify({file_key:Z})))}async function w9($,Z){try{let Y=Xz(Z);if(!Y.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await S($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>e8)return B(`feishu: uploadAndSend oversize — ${Z} (${Y.size}B)`),await S($,`❌ 出站文件: ${s2(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return B(`feishu: uploadAndSend stat failed — ${Z}: ${Y}`),await S($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=TD(Z)?"image":"file",Q=J==="image"?"出站图片":"出站文件";try{let Y=await Dz(Z,J),V=await(J==="image"?$5($,Y):Uz($,Y));if(!V)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await S($,`❌ ${Q}发送失败: ${s2(Z)}(上传已完成)`),!1;return B(`feishu: uploadAndSend ${Z} delivered msg=${V}`),!0}catch(Y){return B(`feishu: uploadAndSend ${Z} failed: ${Y}`),await S($,`❌ ${Q}上传失败: ${s2(Z)} — ${Y}`),!1}}function AJ($){oZ($,{recursive:!0}),B(`feishu: provisioned ${$}`);let Z=sZ(eH(),".codex","config.toml");try{oZ(sZ(eH(),".codex"),{recursive:!0});let J="";try{J=i1(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
215
215
 
216
- `:""}${Y}
216
+ `:""}${Q}
217
217
  trust_level = "trusted"
218
- `,aH(Z,J)}}catch(J){B(`feishu: codex trust write failed for ${$}: ${J}`)}try{dF("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function E9($=m){let Z=aF(c4(),["login","status",...k.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:k.env($,{...process.env,...v.codex.env})});if(Z.error)B(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
219
- ${Z.stderr}`)}function jJ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var sH,tH,dZ,u0,X0,rH=15000,f8="",pH=0,gZ=null,W0,G0,P0,e,lH=200,dH,b0,l8=31457280,QD;var r=O(()=>{o0();S8();EZ();j0();S0();U1();j0();Q0();f();w0();x0();w8();C0();M1();gH();sH=v.feishu.app_id,tH=v.feishu.app_secret,dZ=v.runtime.projects_root,u0=new Map;X0=new iH.Client({appId:sH,appSecret:tH,disableTokenCache:!1});W0=new Map,G0=new Map;P0=new Map;e=new Map;dH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;b0=new Map;QD=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as zz,randomUUID as XD}from"node:crypto";function x9($,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 Gz($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function j$($){let Z=_$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function V$($){return!_$.has($)}function X$($,Z,J){_$.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 S9($){return _$.get($)?.elementCount??0}function Wz($){let Z=_$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function e2($,Z){return _$.get($)?.deadElements.has(Z)??!1}function Kz($,Z){let J=_$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function C9($){let Z=j$($);return Z.sequence+=1,Z.sequence}function LJ($,Z){$.deadElements.add(Z)}function Bz($){return zz("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function KD($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==T.footer)Y.push(J);return zz("sha256").update(Y.sort().join(`
220
- `)).digest("hex")}async function c1($,Z,J){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:XD()}:{}}):void 0,Q=`cardkit ${$} ${Z}`;return f1(Q,async()=>{let V=await E$(),X=AbortSignal.timeout(zD),H;try{return H=await z0(`${HD}${Z}`,{method:$,headers:{Authorization:`Bearer ${V}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:X}),(await p2(H,Q))?.data}catch(z){if(X.aborted&&X.reason?.name==="TimeoutError")throw X.reason;if(H&&z instanceof R$){let G=H.headers.get("x-tt-logid")??H.headers.get("x-request-id")??H.headers.get("request-id")??void 0;if(Object.assign(z,{httpStatus:H.status,logId:G}),G)z.message+=` log_id=${G}`}throw z}})}function BD($){return new Promise((Z)=>setTimeout(Z,$))}function _D($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function jD($){let Z=C9($);await c1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function i8($,Z,J,Y,Q=!1,V={}){let X=(H)=>{let z=typeof H==="object"&&H!==null?H:null,G={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:H instanceof Error?H.message:String(H)};if(x9(G.code,G))G.capacityFingerprint=KD(j$($),V.elementId,V.contentFingerprint);try{if(!Q)j$($).onFailure?.(G.code,G)}catch(W){B(`cardkit failure callback ${$}: ${W}`)}try{Y?.(G)}catch(W){B(`cardkit per-call failure callback ${$}: ${W}`)}};try{await J();return}catch(H){if(!_D(H)){B(`cardkit ${Z} ${$}: ${H}`),X(H);return}B(`cardkit ${Z} ${$}: streaming closed (code=${H.code}) — reopening`)}try{await jD($)}catch(H){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${H}`),X(H);return}try{await J()}catch(H){B(`cardkit ${Z} ${$} retry-after-reopen: ${H}`),X(H)}}function LD($){return typeof $==="object"&&$!==null&&$.code===200740}async function L$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:GD,Y=null;for(let Q=0;Q<J.length;Q++){let V=J[Q]??0;if(V>0)await BD(V);try{let X=await c1("POST","/cards/id_convert",{message_id:$});if(typeof X?.card_id!=="string"||!X.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return X.card_id}catch(X){if(Y=X,!LD(X)||Q===J.length-1)throw X;let H=J[Q+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${H}ms`)}}throw Y}async function G1($){let Z=_$.get($);if(!Z)return;await Z.queue}function U0($,Z,J={},Y){if(V$($))return Promise.resolve();let Q=j$($);if(Q.closing)return Promise.resolve();let V=o$(Z),X=V.element_id,H=Bz(V),z=()=>{if(!X)return;LJ(Q,X),Q.failedAdds.set(X,J)};return Q.queue=Q.queue.then(()=>i8($,"addElement",async()=>{let G=C9($);if(await c1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([V]),sequence:G}),Q.elementCount+=1,X!==T.footer)Q.contentFingerprints.set(X??`#${G}`,H);if(X)Q.deadElements.delete(X),Q.failedAdds.delete(X),Q.failedReplacements.delete(X)},(G)=>{z(),Y?.(G.code,G)},!1,{elementId:X,targetElementId:J.targetElementId,contentFingerprint:H})),Q.queue}function Y0($,Z,J,Y,Q=!0){if(V$($))return Promise.resolve();let V=j$($);if(V.closing)return Promise.resolve();let X=o$(J),H=Bz(X),z=()=>{LJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>i8($,`replaceElement ${Z}`,async()=>{let G=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!G&&!V.failedReplacements.has(Z))return;let W=C9($);if(G)await c1("POST",`/cards/${$}/elements`,{type:G.type??"append",...G.targetElementId?{target_element_id:G.targetElementId}:{},elements:JSON.stringify([X]),sequence:W}),V.elementCount++;else await c1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(X),sequence:W});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.failedReplacements.delete(Z),Z!==T.footer)V.contentFingerprints.set(Z,H)},(G)=>{if(Q)z();Y?.(G.code,G)},!Q,{elementId:Z,contentFingerprint:H})),V.queue}async function A0($,Z,J,Y={}){if(V$($))return!1;let Q=j$($);if(Q.closing)return!1;let V=!1;return await Y0($,Z,J,()=>{V=!0},Y.notifyCardFailure!==!1),!V&&!Q.deadElements.has(Z)}async function _z($,Z,J){if(V$($))return{landed:!1};let Y=j$($);if(Y.closing)return{landed:!1};let Q;return await Y0($,Z,J,(V,X)=>{Q=X}),{landed:!Q&&!Y.deadElements.has(Z),...Q?{failure:Q}:{}}}async function u1($,Z,J={}){return(await $4($,Z,J)).landed}async function $4($,Z,J={}){if(V$($))return{landed:!1};let Y=j$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,V;return await U0($,Z,J,(X,H)=>{V=H}),{landed:!V&&!(Q&&Y.deadElements.has(Q)),...V?{failure:V}:{}}}function PD($,Z,J){if(V$($))return Promise.resolve();let Y=j$($);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(()=>i8($,`deleteElement ${Z}`,async()=>{if(Q())return;let V=C9($);await c1("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Y.elementCount=Math.max(0,Y.elementCount-1),Y.contentFingerprints.delete(Z),Y.failedAdds.delete(Z),Y.failedReplacements.delete(Z),LJ(Y,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Y.queue}async function jz($,Z,J){if(V$($))return!1;let Y=j$($);if(Y.closing)return!1;if(Y.deadElements.has(Z)&&!Y.failedAdds.has(Z)&&!Y.failedReplacements.has(Z))return!0;let Q=!1;return await PD($,Z,(V,X)=>{if(Q=!0,X)J?.(X)}),!Q&&Y.deadElements.has(Z)}function Z4($,Z){if(V$($)||_$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=p1.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},p1.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=p1.get($);if(!Q)return;if(V$($)){p1.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let V=Q.latest;R0($,{config:{summary:{content:V}}}).then((X)=>{let H=p1.get($);if(X&&H===Q)H.lastSent=V})},WD)}function v0($){let Z=p1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;p1.delete($)}function n8($,Z){return R0($,Z).then(()=>{})}async function R0($,Z,J){if(V$($))return!1;let Y=j$($);if(Y.closing)return!1;let Q=!1,V=!1;return Y.queue=Y.queue.then(()=>i8($,"patchSettings",async()=>{if(V$($))return;let X=C9($);await c1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:X}),Q=!0},(X)=>{V=!0,J?.(X)},!0)),await Y.queue,Q&&!V&&!V$($)}async function H$($){let Z=_$.get($);if(!Z){v0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,v0($),await Z.queue,_$.delete($)}var HD="https://open.feishu.cn/open-apis/cardkit/v1",zD=15000,GD,_$,p1,WD=1500;var f$=O(()=>{o0();r();S8();f();C0();GD=[0,250,750,1500];_$=new Map,p1=new Map});class b9{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(Lz($))}update($,Z=!1){return this.updateRow(Lz($),Z)}syncBackground($,Z,J){return B$($,async()=>{let Y=this.background.get(Z);if(!Y)this.background.set(Z,Y=new Map);let Q=[];for(let V of J){let X=V.displayId??V.toolUseId??V.id,H=Y.get(X);if(H?.task===V&&!H.pendingSettings)continue;let z=H&&G$(H.task)&&!G$(V),G=(H?.version??0)+(z?1:0),W=`background:${Z}:${X}:${G}`,K={key:W,chatId:$,elementId:l4.panel(W),element:e5({...V,id:W}),summary:k3(V),status:V.status,terminal:G$(V)};try{if(!H||z)await this.addRow(K);else await this.updateRow(K,K.terminal,!0);Y.set(X,{task:V,version:G})}catch(_){if(this.byTask.get(W)?.rows.get(W)===K)Y.set(X,{task:V,version:G,pendingSettings:!0});Q.push(_)}}if(Q.length)throw AggregateError(Q,Q.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return B$($.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)<qD){let Q=await this.deps.addElementResult(J.cardId,$.element);if(Q.landed){this.attach(J,$),await this.settings(J);return}if(!Pz(Q))throw a8("agent card append",Q)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1){return B$($.chatId,async()=>{let Y=this.byTask.get($.key);if(!Y)return;if(Y.settled.has($.key)&&!J){if(Z)await this.settings(Y);return}if(Y.settled.size===Y.rows.size)Y.settingsJson=void 0;let Q=[],V=await this.deps.replaceElementResult(Y.cardId,$.elementId,$.element);if(!V.landed){if(!Pz(V)||Y.rows.size===1)throw a8("agent task row update",V);let X=Y;await this.seal(X,!0);let H=this.tails.get($.chatId);if(H)await this.seal(H);Y=await this.create($),X.rows.delete($.key),X.settled.delete($.key);try{let z;if(!await this.deps.deleteElementChecked(X.cardId,$.elementId,(G)=>{z=G})){let G=a8("agent moved task row deletion",{landed:!1,failure:z});throw Error(`${G.message}; the previous card may still show its earlier state`)}}catch(z){Q.push(String(z))}try{await this.settings(X)}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(X){Q.push(String(X))}if(Q.length)throw Error(Q.join("; "))})}closeChat($){return B$($,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:DZ([...$.rows.values()])}}},Q=JSON.stringify(Y);if(Q!==$.settingsJson){let V;if(!await this.deps.patchSettingsChecked($.cardId,Y,(X)=>{V=X}))throw a8("agent card settings update",{landed:!1,failure:V});$.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 Lz($){return{key:`run:${$.runId}`,chatId:$.chatId,elementId:T8($.runId),element:FZ($),summary:E8($),status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",attach:(Z)=>{$.cardMessageId=Z}}}function Pz($){return x9($.failure?.code,$.failure)}function a8($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"}${Z.failure.logId?`, log_id=${Z.failure.logId}`:""})`:""}`)}var qD=50;var PJ=O(()=>{Q$();f$();EZ()});function qz(){return new b9(qJ)}var qJ;var FJ=O(()=>{PJ();f$();r();qJ={sendCard:u,getChatTailMessageId:KJ,convertMessageToCard:L$,recordCardCreated:X$,getElementCount:S9,addElementResult:$4,replaceElementResult:_z,deleteElementChecked:jz,cancelSummary:v0,patchSettingsChecked:R0,dispose:H$}});var Dz={};S$(Dz,{codexAccountSummary:()=>k9,codexAccountPanel:()=>y9,codexAccountCard:()=>P$,CODEX_ACCOUNTS_PAGE_SIZE:()=>o8});function W1($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function DJ($){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 k9($){let[Z,J]=Fz[$.phase],Y=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Y?`${Y} · `:""}${$.title??J}`}function P$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:k9($)}},body:{elements:[y9($)]}}}function y9($){let[,,Z]=Fz[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Y=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(f0(["连接","授权","就绪"].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(DJ([[i0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[f0(`[**打开授权页 ↗**](${Y.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),i0("登录账号,输入左侧验证码")]]))}if($.current)J.push(DJ([[i0("当前使用"),f0(`**${W1($.current)}**`)],...$.selected&&$.selected!==$.current?[[i0("下次启动"),f0(`**${W1($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(f0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Y)=>W1(Y)).join(" · ")));if($.message)J.push(f0(W1($.message)));if($.resetUsage){let Y=$.resetUsage;if(J.push(f0(`**重置卡** ${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(...r6(Q,V))}else J.push(f0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...FD($));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:[f0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
221
- `)),i0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(i0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[f0(W1($.details))]});return{tag:"collapsible_panel",element_id:T.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:k9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function FD($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/o8)),Y=$.page??1;if(!Number.isInteger(Y)||Y<1||Y>J)throw Error(`页码应为 1–${J}`);let Q=[i0(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],V=$.scheduling?.candidates.filter((X)=>X.state==="ready").sort((X,H)=>H.score-X.score||(H.availableNow??0)-(X.availableNow??0)||X.account.id.localeCompare(H.account.id));if($.scheduling)Q.push(i0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let X of Z.entries.slice((Y-1)*o8,Y*o8)){let H=[X.account.id===$.currentId?"使用中":"",X.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),z=X.usage,G=[];if(Q.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${X.account.name}${H.length?` · ${H.join(" · ")}`:""}`},background_color:X.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:G}),X.duplicateOf){G.push(i0(`与「${X.duplicateOf}」同一账号,合计只计一次`));continue}let W=$.scheduling?.candidates.find((L)=>L.account.id===X.account.id);if(W){let L=V.findIndex((j)=>j.account.id===X.account.id);if(G.push(W.state==="ready"?f0(`**#${L+1} · ${W.score.toPrecision(3)} 份/h**`):i0(W.state==="exhausted"?"⏳ 耗尽 · 暂不参与":W.state==="excluded"?"Ultra 自动排除 Plus":W.state==="waiting"?`⏳ 周余量 ${W.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),W.state==="ready"&&W.remaining!=null)G.push(i0(`周余量 ${W.remaining.toPrecision(3)} 份${W.fiveHourRemaining!=null?` · 5h ${W.fiveHourRemaining.toPrecision(3)} 份`:""}`));if(W.state==="miss"&&W.reason&&z.state==="ok")G.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[f0(W1(W.reason))]})}if(z.state!=="ok"){if(G.push(f0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)G.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[f0(W1(z.reason))]});continue}let K=z.subscriptionType==="pro"?"Pro 20×":z.subscriptionType==="prolite"?"Pro 5×":z.subscriptionType==="plus"?"Plus 1×":z.subscriptionType??"套餐 MISS";G.push(i0(`${K} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([L,j])=>L?[r6(L,j)]:[]);if(_.length)G.push(DJ(_))}if(J>1)Q.push(i0(`${Y}/${J} 页 · ${Y<J?`下一页 codex-accounts ${Y+1}`:"首页 codex-accounts"}`));return Q}var o8=4,Fz,f0=($)=>({tag:"markdown",content:$}),i0=($)=>({tag:"markdown",content:`<font color='grey'>${W1($)}</font>`,text_size:"notation"});var J4=O(()=>{C0();Fz={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 MJ($){let Z=new Map,J=$.map((W)=>{let K=W.fingerprint?Z.get(W.fingerprint):void 0;if(W.fingerprint&&!K)Z.set(W.fingerprint,W.account.name);return{...W,...K?{duplicateOf:K}:{}}}),Y=J.filter((W)=>!W.duplicateOf),V=(Y.length<=1||Y.every((W)=>W.fingerprint!==null))&&Y.every((W)=>W.usage.state==="ok"),X=Y.flatMap((W)=>W.usage.state==="ok"?[W.usage]:[]),H=V&&X.every((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent!==null))?X.filter((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,z=V&&X.every((W)=>W.resetCredits!=null)?X.reduce((W,K)=>W+K.resetCredits,0):null,G=["fiveHour","weekly"].map((W)=>{let K=X.map((L)=>L[W]).filter((L)=>L!==null),_=V&&K.every((L)=>L.percent!==null&&L.percent>=0&&L.percent<=100);return{kind:W,count:K.length,remaining:_?K.reduce((L,j)=>L+(100-j.percent)/100,0):null}}).filter((W)=>W.count||!V);return{entries:J,complete:V,available:H,resetCredits:z,windows:G}}async function s8($){let Z=new Map,J=await Promise.all(k.list().map(async(Y)=>{let Q=null;try{Q=k.fingerprint(Y.id)}catch(z){return{account:Y,fingerprint:Q,usage:{state:"network",reason:`账号身份读取失败:${String(z)}`}}}let V=Q??Y.id,X=Z.get(V);if(!X)X=$?.id===Y.id?Promise.resolve($.usage):h2(Y.id),Z.set(V,X);let H=await X;if(H.state==="ok"&&H.accountFingerprint)Q=H.accountFingerprint;return{account:Y,usage:H,fingerprint:Q}}));return MJ(J)}var UJ=O(()=>{w0();A$()});import{homedir as DD}from"node:os";function UD($,Z=MD){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 Mz($){return typeof $==="string"&&AD.includes($)?$:null}async function t8($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (S2(),K6)),J=new Z({workDir:DD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Y)=>B(`Claude model catalog MISS: ${Y.message}`));try{let Y=await UD(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 Uz($="default"){let Z=new r$({accountId:$});try{if(await Z.initialize("lodestar-models"),(await E1(()=>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 E1(()=>Z.request("model/list",{}),"模型查询");if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let Q=Y.data,V=[];for(let X of Q){if(!X||X.hidden||!X.id)continue;let H=(Array.isArray(X.supportedReasoningEfforts)?X.supportedReasoningEfforts:[]).map((G)=>Mz(G?.reasoningEffort)).filter((G)=>G!==null);if(!H.length)continue;let z=Mz(X.defaultReasoningEffort)??H[0];V.push({model:String(X.id),display:typeof X.displayName==="string"&&X.displayName?String(X.displayName):String(X.id),efforts:H,defaultEffort:z})}if(!V.length)throw Error("Codex model/list 未返回可用模型");return V}finally{await Z.close()}}async function Az($,Z){return(await _2($,Z)).map((Y)=>({model:Y,display:Y,efforts:Y4,defaultEffort:"max"}))}var MD=1e4,AD,Y4;var Q4=O(()=>{x4();A$();f();AD=["none","minimal","low","medium","high","xhigh","max","ultra"];Y4=["max","xhigh","high","medium","low"]});function q0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function AJ($,Z){let J=$.agent==="claude"?M5.filter((Q)=>Q!=="default"):$.agent==="codex"?[...m5]:["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 r8($,Z){let J=$.modelSelection,Y=new Set(q0(Z.hidden_models)),Q=[...new Set([...q0(Z.custom_models),...J?[]:q0(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},X=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.modelIds=[];try{await X()}catch(W){throw $.models=[],$.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W instanceof Error?W.message:String(W)},W}if($.modelCatalogState?.status!=="ready")return;let H=$.models,z=(J?V.availableModels:H).map((W)=>({...W,origin:W.origin??"upstream"}));for(let W of Q){if(z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))continue;z.push({model:W,display:W,origin:"custom",...AJ($,Z)})}V.availableModels=z;let G=J?H.map((W)=>z.find((K)=>K.model===W.model)??{...W,origin:"upstream"}):z;$.models=[...G.filter((W)=>W.origin==="custom"||!Y.has(W.model)),...z.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],V.modelIds=$.models.map((W)=>W.model)},$}var d1=O(()=>{j0();U1()});import{existsSync as OD}from"node:fs";import{join as ND}from"node:path";function Oz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function OJ($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(Oz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(Oz($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function Nz($){return $===m||OD(ND(k.home($),"auth.json"))}var NJ=O(()=>{S0();Z0();A$();Q4();f();w0();d1();M0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let X=Nz(V),H=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,G={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,k.revision(V)]),enabled:X,models:[],modelCatalogState:{status:X?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(G.enabled=Nz(V),!G.enabled){G.models=[],G.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}G.modelCatalogState={status:"loading",updatedAt:null};try{if(G.models=await Uz(V),z)for(let W of G.models)W.defaultEffort=z;if(!H)G.defaultModel=G.models[0]?.model??"";G.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){if(B(`codex-sub ${V} refreshModels MISS: ${W?.message??W}`),G.models=[],W?.code==="CODEX_AUTH_MISSING")G.enabled=!1;G.modelCatalogState={status:G.enabled?"failed":"disabled",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let K=r0(W);return Object.assign(K,v.codex.env),k.env(V,K)},resolveSpawnModel(W){return W},async readUsage(){return OJ(await h2(V))}};return G},Y=J(m);Y.forAccount=(V)=>{if(V===m)return Y;let X=k.revision(V),H=Z.get(V);if(H?.revision===X)return H.source;let z=r8(J(V),$);return Z.set(V,{revision:X,source:z}),z};let Q=Y.refreshModels.bind(Y);return Y.refreshModels=async()=>{await Promise.all([Q(),...k.list().filter((V)=>V.id!==m).map((V)=>Y.forAccount(V.id).refreshModels())])},Y}})});function Rz($){return Z7.find((Z)=>Z.other===$)?.id??$}function Tz($){let Z=Z7.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function w9($){let Z=$.api_key?.trim(),J=$.auth_token?.trim();if(Z&&J&&Z!==J)throw Error("同一账号的 api_key 与 auth_token 不一致,请重新配置");return Z||J}function $7($,Z){let J=new URL(Z);if(!["http:","https:"].includes(J.protocol)||J.username||J.password||J.search||J.hash)throw Error(`${$.id} 接口地址必须是无凭据、查询参数和 fragment 的 HTTP(S) 地址`);if($.id==="glm")return E4(`${J.origin}/api/anthropic`);if(J.pathname=J.pathname.replace(/\/+$/,""),J.hostname==="api.deepseek.com"&&["/","/v1"].includes(J.pathname))J.pathname="/anthropic";return J.toString().replace(/\/+$/,"")}function e8($,Z){let J=$7($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function V4($){let{api_key:Z,auth_token:J,base_url:Y,...Q}=$;return Q}function RJ($,Z,J={}){let Y=Z[$.id]??{},Q=Z[$.other]??{},V=w9(Y),X=w9(Q),H=Y.base_url?.trim(),z=Q.base_url?.trim();if(V&&X&&V!==X||H&&z&&e8($,H)!==e8($,z))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:$7($,H||z||$.base)};let G=J[$.id]??J[$.other]??{};if(w9(G)&&(H||z)&&G.base_url&&e8($,H||z)!==e8($,G.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:w9(G),base:$7($,H||z||G.base_url||$.base)}}function J7($,Z={}){let J={...$};for(let Y of Z7){let{key:Q,base:V}=RJ(Y,$,Z);J[Y.id]={...V4($[Y.id]??{}),base_url:V,...Y.id==="glm"?{auth_token:Q??""}:{api_key:Q??""}},J[Y.other]={...V4($[Y.other]??{}),api_key:Q??"",base_url:Y.id==="glm"?`${new URL(V).origin}/api/coding/paas/v4`:V.replace(/\/anthropic$/,"")}}return J}function TJ($,Z,J){let Y=Object.fromEntries(Object.entries(J).filter(([,z])=>z!==void 0)),Q={...$,[Z]:{...$[Z],...Y}},V=Z7.find((z)=>z.id===Z||z.other===Z);if(!V)return{[Z]:Q[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,H=J.base_url!==void 0;if(X||H){let z=$[Z]??{},G=$[V.id]??{},W=$[V.other]??{},K=X?w9(J):RJ(V,$).key,_=$7(V,J.base_url?.trim()||z.base_url||G.base_url||W.base_url||V.base);Q[V.id]={...V4(Q[V.id]??{}),base_url:_,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Q[V.other]=V4(Q[V.other]??{})}else{let{key:z,base:G}=RJ(V,Q);Q[V.id]={...V4(Q[V.id]??{}),base_url:G,...V.id==="glm"?{auth_token:z??""}:{api_key:z??""}},Q[V.other]=V4(Q[V.other]??{})}return{[V.id]:Q[V.id],[V.other]:Q[V.other]}}var Z7;var v9=O(()=>{x4();Z7=[{id:"deepseek",other:"deepseek-harness",base:"https://api.deepseek.com/anthropic"},{id:"glm",other:"dsh-glm",base:"https://open.bigmodel.cn/api/anthropic"}]});function EJ(){return JSON.stringify([_6(),XX(),$$().map(($)=>[$.id,$.enabled,$.spawnRevision]),k.list().map(($)=>[$.id,$.name,$.revision])])}function xJ(){return h9&&h9.key===EJ()&&Date.now()<h9.until?h9.rows:void 0}function Ez(){let $=xJ();if($)return Promise.resolve($);let Z=EJ();if(f9?.key===Z)return f9.promise;let J=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],Y=(z)=>J.includes(z)?J.indexOf(z):J.length,Q=$$().filter((z)=>z.enabled||z.kind==="codex-subscription"&&k.list().some((G)=>G.id!=="default")).sort((z,G)=>Y(z.id)-Y(G.id)),V=new Set,X=[];for(let z of Q){if(z.kind==="codex-subscription"){X.push(s8().then((K)=>K.entries.filter((_)=>!_.duplicateOf).map((_)=>({id:`codex:${_.account.id}`,label:`Codex·${_.account.name}`,usage:OJ(_.usage)}))));continue}let G=Rz(z.id);if(V.has(G))continue;V.add(G);let W=G==="glm"?"GLM Coding Plan":G==="deepseek"?"DeepSeek":z.kind==="claude-subscription"?"Claude 订阅":z.display;X.push(Promise.resolve().then(()=>z.readUsage()).catch((K)=>{let _=K instanceof Error?K.message:String(K);return B(`account usage ${G} MISS: ${_}`),{state:"network",windows:[],reason:_}}).then((K)=>[{id:G,label:W,usage:K}]))}let H=Promise.all(X).then((z)=>{let G=z.flat(),W=Date.now(),K=Math.min(W+t$,...G.map((_)=>(_.usage.fetchedAt??W)+t$));if(Z===EJ())h9={key:Z,rows:G,until:K};return G}).finally(()=>{if(f9?.promise===H)f9=void 0});return f9={key:Z,promise:H},H}var h9,f9;var xz=O(()=>{w0();UJ();NJ();Z0();v9();A$();T1();f()});import{homedir as RD}from"node:os";function Q7($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function Y7($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!Q7($))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 Cz($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function bz($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=Cz(i4(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&&Cz(V)===J});if(Y.length>1)return B(`Claude weekly usage MISS: ${Z} 匹配多个模型专属周额度窗口`),null;if(Y.length===1)return Y[0];return $.windows.find((Q)=>Q.kind==="weekly")??null}function ED($){if(!Q7($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!Q7($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[Y7(Z.five_hour,"fiveHour","5h 窗口"),Y7(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(Y7(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(!Q7(Q)||typeof Q.display_name!=="string"||!Q.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Q.display_name.trim();J.push(Y7(Q,`modelWeekly:${V}`,`${V} 周额度`)),Y=!0}}if(!Y)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function kz($){return TD.read("claude-subscription",()=>xD($))}async function xD($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (S2(),K6)),J=new Z({workDir:RD(),effort:"default",allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(V)=>B(`Claude subscription usage MISS: ${V.message}`));let Y,Q;try{let V=await Promise.race([J.readSubscriptionUsage(),new Promise((X,H)=>{Y=setTimeout(()=>H(Error(`Claude 订阅额度查询超时(${Sz/1000}s)`)),Sz)})]);return ED(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 B(`claude-sub readUsage MISS: ${J}`),{state:Z?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING"?"no_credentials":v2(Z)?"rate_limited":"network",windows:[],reason:J}}}var Sz=30000,TD;var SJ=O(()=>{f();Y6();T1();TD=new W$});function yz($){let Z=[];for(let J of $.matchAll(SD)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function V7($,Z=process.platform){if(Z!=="win32")return $;let J=CD.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var SD,CD;var CJ=O(()=>{SD=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;CD=/^\/([a-zA-Z])\//});function fz($){if(wz.test($))return{marker:"start",body:$.replace(wz,"")};if(vz.test($))return{marker:"end",body:$.replace(vz,"")};return{marker:"none",body:$}}var wz,vz;var hz=O(()=>{wz=/^>{3,}[ \t]?/,vz=/^<{3,}[ \t]?/});async function Iz($,Z,J,Y,Q){let{marker:V,body:X}=fz(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)kJ($,"reopen");return $.multiMsgBuffer=[],bJ($,X,J,Y,Q),!0}if(V==="end"){if($.multiMsgBuffer===null){if(X.trim()||J.length)return!1;return B(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}bJ($,X,J,Y,Q);let{multiMsgBuffer:H,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await kD($,H,z),!0}if($.multiMsgBuffer!==null)return bJ($,Z,J,Y,Q),!0;return!1}function bJ($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)bD($,Q)}function bD($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await d0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else k0(Z,J)})()}async function kD($,Z,J){for(let[X,H]of J)if(H)k0(X,H);let Y=Z.filter((X)=>X.text.trim()||X.files.length);if(Y.length===0){B(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await E($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((X)=>{return(X.files.length?X.files.map((z)=>`[file: ${z}]`).join(" ")+`
218
+ `,Hz(Z,J)}}catch(J){B(`feishu: codex trust write failed for ${$}: ${J}`)}try{BD("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function y9($=p){let Z=LD(a4(),["login","status",...y.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:y.env($,{...process.env,...g.codex.env})});if(Z.error)B(`codex login status failed: ${Z.error.message}`);return Z.status===0&&/Logged in using ChatGPT/i.test(`${Z.stdout}
219
+ ${Z.stderr}`)}function OJ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var Wz,Gz,$J,o0,z0,Kz=15000,d8="",$z=0,aZ=null,B0,K0,P0,$0,Qz=200,Yz,b0,e8=31457280,RD;var r=O(()=>{u0();I8();fZ();G0();S0();J1();G0();V0();h();f0();x0();u8();C0();C1();rH();Wz=g.feishu.app_id,Gz=g.feishu.app_secret,$J=g.runtime.projects_root,o0=new Map;z0=new Vz.Client({appId:Wz,appSecret:Gz,disableTokenCache:!1});B0=new Map,K0=new Map;P0=new Map;$0=new Map;Yz=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;b0=new Map;RD=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as Mz,randomUUID as ED}from"node:crypto";function v9($,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 Az($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function q$($){let Z=L$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function z$($){return!L$.has($)}function W$($,Z,J){L$.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 f9($){return L$.get($)?.elementCount??0}function Oz($){let Z=L$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function Y4($,Z){return L$.get($)?.deadElements.has(Z)??!1}function Nz($,Z){let J=L$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function h9($){let Z=q$($);return Z.sequence+=1,Z.sequence}function NJ($,Z){$.deadElements.add(Z)}function Rz($){return Mz("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function kD($,Z,J){let Q=[...$.contentFingerprints].filter(([Y])=>Y!==Z).map(([,Y])=>Y);if(J&&Z!==E.footer)Q.push(J);return Mz("sha256").update(Q.sort().join(`
220
+ `)).digest("hex")}async function o1($,Z,J){let Q=J?JSON.stringify({...J,..."sequence"in J?{uuid:ED()}:{}}):void 0,Y=`cardkit ${$} ${Z}`;return u1(Y,async()=>{let V=await b$(),X=AbortSignal.timeout(SD),H;try{return H=await X0(`${xD}${Z}`,{method:$,headers:{Authorization:`Bearer ${V}`,"Content-Type":"application/json"},...Q!==void 0?{body:Q}:{},signal:X}),(await i2(H,Y))?.data}catch(z){if(X.aborted&&X.reason?.name==="TimeoutError")throw X.reason;if(H&&z instanceof S$){let W=H.headers.get("x-tt-logid")??H.headers.get("x-request-id")??H.headers.get("request-id")??void 0;if(Object.assign(z,{httpStatus:H.status,logId:W}),W)z.message+=` log_id=${W}`}throw z}})}function wD($){return new Promise((Z)=>setTimeout(Z,$))}function yD($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function vD($){let Z=h9($);await o1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function Z5($,Z,J,Q,Y=!1,V={}){let X=(H)=>{let z=typeof H==="object"&&H!==null?H:null,W={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:H instanceof Error?H.message:String(H)};if(v9(W.code,W))W.capacityFingerprint=kD(q$($),V.elementId,V.contentFingerprint);try{if(!Y)q$($).onFailure?.(W.code,W)}catch(G){B(`cardkit failure callback ${$}: ${G}`)}try{Q?.(W)}catch(G){B(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(H){if(!yD(H)){B(`cardkit ${Z} ${$}: ${H}`),X(H);return}B(`cardkit ${Z} ${$}: streaming closed (code=${H.code}) — reopening`)}try{await vD($)}catch(H){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${H}`),X(H);return}try{await J()}catch(H){B(`cardkit ${Z} ${$} retry-after-reopen: ${H}`),X(H)}}function fD($){return typeof $==="object"&&$!==null&&$.code===200740}async function F$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:CD,Q=null;for(let Y=0;Y<J.length;Y++){let V=J[Y]??0;if(V>0)await wD(V);try{let X=await o1("POST","/cards/id_convert",{message_id:$});if(typeof X?.card_id!=="string"||!X.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return X.card_id}catch(X){if(Q=X,!fD(X)||Y===J.length-1)throw X;let H=J[Y+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${H}ms`)}}throw Q}async function P1($){let Z=L$.get($);if(!Z)return;await Z.queue}function M0($,Z,J={},Q){if(z$($))return Promise.resolve();let Y=q$($);if(Y.closing)return Promise.resolve();let V=Q1(Z),X=V.element_id,H=Rz(V),z=()=>{if(!X)return;NJ(Y,X),Y.failedAdds.set(X,J)};return Y.queue=Y.queue.then(()=>Z5($,"addElement",async()=>{let W=h9($);if(await o1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([V]),sequence:W}),Y.elementCount+=1,X!==E.footer)Y.contentFingerprints.set(X??`#${W}`,H);if(X)Y.deadElements.delete(X),Y.failedAdds.delete(X),Y.failedReplacements.delete(X)},(W)=>{z(),Q?.(W.code,W)},!1,{elementId:X,targetElementId:J.targetElementId,contentFingerprint:H})),Y.queue}function Y0($,Z,J,Q,Y=!0){if(z$($))return Promise.resolve();let V=q$($);if(V.closing)return Promise.resolve();let X=Q1(J),H=Rz(X),z=()=>{NJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>Z5($,`replaceElement ${Z}`,async()=>{let W=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!W&&!V.failedReplacements.has(Z))return;let G=h9($);if(W)await o1("POST",`/cards/${$}/elements`,{type:W.type??"append",...W.targetElementId?{target_element_id:W.targetElementId}:{},elements:JSON.stringify([X]),sequence:G}),V.elementCount++;else await o1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(X),sequence:G});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.failedReplacements.delete(Z),Z!==E.footer)V.contentFingerprints.set(Z,H)},(W)=>{if(Y)z();Q?.(W.code,W)},!Y,{elementId:Z,contentFingerprint:H})),V.queue}async function A0($,Z,J,Q={}){if(z$($))return!1;let Y=q$($);if(Y.closing)return!1;let V=!1;return await Y0($,Z,J,()=>{V=!0},Q.notifyCardFailure!==!1),!V&&!Y.deadElements.has(Z)}async function Tz($,Z,J){if(z$($))return{landed:!1};let Q=q$($);if(Q.closing)return{landed:!1};let Y;return await Y0($,Z,J,(V,X)=>{Y=X}),{landed:!Y&&!Q.deadElements.has(Z),...Y?{failure:Y}:{}}}async function s1($,Z,J={}){return(await V4($,Z,J)).landed}async function V4($,Z,J={}){if(z$($))return{landed:!1};let Q=q$($);if(Q.closing)return{landed:!1};let Y=Z.element_id,V;return await M0($,Z,J,(X,H)=>{V=H}),{landed:!V&&!(Y&&Q.deadElements.has(Y)),...V?{failure:V}:{}}}function hD($,Z,J){if(z$($))return Promise.resolve();let Q=q$($);if(Q.closing)return Promise.resolve();let Y=()=>Q.deadElements.has(Z)&&!Q.failedAdds.has(Z)&&!Q.failedReplacements.has(Z);if(Y())return Promise.resolve();return Q.queue=Q.queue.then(()=>Z5($,`deleteElement ${Z}`,async()=>{if(Y())return;let V=h9($);await o1("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Q.elementCount=Math.max(0,Q.elementCount-1),Q.contentFingerprints.delete(Z),Q.failedAdds.delete(Z),Q.failedReplacements.delete(Z),NJ(Q,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Q.queue}async function Ez($,Z,J){if(z$($))return!1;let Q=q$($);if(Q.closing)return!1;if(Q.deadElements.has(Z)&&!Q.failedAdds.has(Z)&&!Q.failedReplacements.has(Z))return!0;let Y=!1;return await hD($,Z,(V,X)=>{if(Y=!0,X)J?.(X)}),!Y&&Q.deadElements.has(Z)}function X4($,Z){if(z$($)||L$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=a1.get($);if(!Q)Q={latest:J,lastSent:"",timer:null},a1.set($,Q);else Q.latest=J;if(Q.timer)return;Q.timer=setTimeout(()=>{let Y=a1.get($);if(!Y)return;if(z$($)){a1.delete($);return}if(Y.timer=null,Y.latest===Y.lastSent)return;let V=Y.latest;R0($,{config:{summary:{content:V}}}).then((X)=>{let H=a1.get($);if(X&&H===Y)H.lastSent=V})},bD)}function g0($){let Z=a1.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;a1.delete($)}function J5($,Z){return R0($,Z).then(()=>{})}async function R0($,Z,J){if(z$($))return!1;let Q=q$($);if(Q.closing)return!1;let Y=!1,V=!1;return Q.queue=Q.queue.then(()=>Z5($,"patchSettings",async()=>{if(z$($))return;let X=h9($);await o1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:X}),Y=!0},(X)=>{V=!0,J?.(X)},!0)),await Q.queue,Y&&!V&&!z$($)}async function G$($){let Z=L$.get($);if(!Z){g0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,g0($),await Z.queue,L$.delete($)}var xD="https://open.feishu.cn/open-apis/cardkit/v1",SD=15000,CD,L$,a1,bD=1500;var u$=O(()=>{u0();r();I8();h();C0();CD=[0,250,750,1500];L$=new Map,a1=new Map});class I9{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(xz($))}update($,Z=!1){return this.updateRow(xz($),Z)}syncBackground($,Z,J){return j$($,async()=>{let Q=this.background.get(Z);if(!Q)this.background.set(Z,Q=new Map);let Y=[];for(let V of J){let X=V.displayId??V.toolUseId??V.id,H=Q.get(X);if(H?.task===V&&!H.pendingSettings)continue;let z=H&&B$(H.task)&&!B$(V),W=(H?.version??0)+(z?1:0),G=`background:${Z}:${X}:${W}`,K={key:G,chatId:$,elementId:t4.panel(G),element:z6({...V,id:G}),summary:p3(V),status:V.status,terminal:B$(V)};try{if(!H||z)await this.addRow(K);else await this.updateRow(K,K.terminal,!0);Q.set(X,{task:V,version:W})}catch(_){if(this.byTask.get(G)?.rows.get(G)===K)Q.set(X,{task:V,version:W,pendingSettings:!0});Y.push(_)}}if(Y.length)throw AggregateError(Y,Y.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return j$($.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)<ID){let Y=await this.deps.addElementResult(J.cardId,$.element);if(Y.landed){this.attach(J,$),await this.settings(J);return}if(!Sz(Y))throw Q5("agent card append",Y)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1){return j$($.chatId,async()=>{let Q=this.byTask.get($.key);if(!Q)return;if(Q.settled.has($.key)&&!J){if(Z)await this.settings(Q);return}if(Q.settled.size===Q.rows.size)Q.settingsJson=void 0;let Y=[],V=await this.deps.replaceElementResult(Q.cardId,$.elementId,$.element);if(!V.landed){if(!Sz(V)||Q.rows.size===1)throw Q5("agent task row update",V);let X=Q;await this.seal(X,!0);let H=this.tails.get($.chatId);if(H)await this.seal(H);Q=await this.create($),X.rows.delete($.key),X.settled.delete($.key);try{let z;if(!await this.deps.deleteElementChecked(X.cardId,$.elementId,(W)=>{z=W})){let W=Q5("agent moved task row deletion",{landed:!1,failure:z});throw Error(`${W.message}; the previous card may still show its earlier state`)}}catch(z){Y.push(String(z))}try{await this.settings(X)}catch(z){Y.push(String(z))}}if(Q.rows.set($.key,$),Z)Q.settled.add($.key);else Q.settled.delete($.key);try{await this.settings(Q)}catch(X){Y.push(String(X))}if(Y.length)throw Error(Y.join("; "))})}closeChat($){return j$($,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 Q={cardId:J,messageId:Z,chatId:$.chatId,rows:new Map,settled:new Set,sealed:!1};return this.attach(Q,$),this.tails.set($.chatId,Q),Q}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,Q={config:{streaming_mode:!J,summary:{content:xZ([...$.rows.values()])}}},Y=JSON.stringify(Q);if(Y!==$.settingsJson){let V;if(!await this.deps.patchSettingsChecked($.cardId,Q,(X)=>{V=X}))throw Q5("agent card settings update",{landed:!1,failure:V});$.settingsJson=Y}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 xz($){return{key:`run:${$.runId}`,chatId:$.chatId,elementId:v8($.runId),element:EZ($),summary:f8($),status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",attach:(Z)=>{$.cardMessageId=Z}}}function Sz($){return v9($.failure?.code,$.failure)}function Q5($,Z){return Error(`${$} MISS${Z.failure?`: ${Z.failure.message} (code=${Z.failure.code??"MISS"}${Z.failure.logId?`, log_id=${Z.failure.logId}`:""})`:""}`)}var ID=50;var RJ=O(()=>{H$();u$();fZ()});function Cz(){return new I9(TJ)}var TJ;var EJ=O(()=>{RJ();u$();r();TJ={sendCard:u,getChatTailMessageId:UJ,convertMessageToCard:F$,recordCardCreated:W$,getElementCount:f9,addElementResult:V4,replaceElementResult:Tz,deleteElementChecked:Ez,cancelSummary:g0,patchSettingsChecked:R0,dispose:G$}});var kz={};v$(kz,{codexAccountSummary:()=>g9,codexAccountPanel:()=>m9,codexAccountCard:()=>P$,CODEX_ACCOUNTS_PAGE_SIZE:()=>Y5});function D1($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function xJ($){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 g9($){let[Z,J]=bz[$.phase],Q=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Q?`${Q} · `:""}${$.title??J}`}function P$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:g9($)}},body:{elements:[m9($)]}}}function m9($){let[,,Z]=bz[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Q=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(m0(["连接","授权","就绪"].map((Y,V)=>V===Q?`**${V+1} ${Y}**`:`${V<Q?"✓":V+1} ${Y}`).join(" → ")))}if($.phase==="waiting"&&$.verification){let Q=new URL($.verification.url);if(Q.protocol!=="https:"||/[\s<>]/.test($.verification.url))throw Error("授权链接无效");if(!/^[A-Za-z0-9-]{1,64}$/.test($.verification.code))throw Error("验证码格式无效");J.push(xJ([[r0("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[m0(`[**打开授权页 ↗**](${Q.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),r0("登录账号,输入左侧验证码")]]))}if($.current)J.push(xJ([[r0("当前使用"),m0(`**${D1($.current)}**`)],...$.selected&&$.selected!==$.current?[[r0("下次启动"),m0(`**${D1($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(m0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Q)=>D1(Q)).join(" · ")));if($.message)J.push(m0(D1($.message)));if($.resetUsage){let Q=$.resetUsage;if(J.push(m0(`**重置卡** ${Q.state==="ok"&&Q.resetCredits!=null?`${Q.resetCredits} 次可用`:"MISS"}`)),Q.state==="ok"){for(let[Y,V]of[[Q.fiveHour,"5h"],[Q.weekly,"周"]])if(Y)J.push(...HZ(Y,V))}else J.push(m0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...gD($));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:[m0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
221
+ `)),r0("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(r0($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[m0(D1($.details))]});return{tag:"collapsible_panel",element_id:E.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:g9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:"12px",elements:J}}function gD($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/Y5)),Q=$.page??1;if(!Number.isInteger(Q)||Q<1||Q>J)throw Error(`页码应为 1–${J}`);let Y=[r0(`${Z.entries.length} 个记录 · 可用 ${Z.available??"MISS"} 个账号${Z.complete?"":" · 汇总不完整"}`)],V=$.scheduling?.candidates.filter((X)=>X.state==="ready").sort((X,H)=>H.score-X.score||(H.availableNow??0)-(X.availableNow??0)||X.account.id.localeCompare(H.account.id));if($.scheduling)Y.push(r0(`${$.scheduling.ultra?"Ultra · Pro ≥ 0.5 份":"普通 · 周 / 5h 综合"} · 最高分优先 · 可调度 ${V.length}`));for(let X of Z.entries.slice((Q-1)*Y5,Q*Y5)){let H=[X.account.id===$.currentId?"使用中":"",X.account.id===$.selectedId&&$.selectedId!==$.currentId?"下次启动":""].filter(Boolean),z=X.usage,W=[];if(Y.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`${X.account.name}${H.length?` · ${H.join(" · ")}`:""}`},background_color:X.account.id===$.currentId?"blue-50":"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"4px",elements:W}),X.duplicateOf){W.push(r0(`与「${X.duplicateOf}」同一账号,合计只计一次`));continue}let G=$.scheduling?.candidates.find((L)=>L.account.id===X.account.id);if(G){let L=V.findIndex((j)=>j.account.id===X.account.id);if(W.push(G.state==="ready"?m0(`**#${L+1} · ${G.score.toPrecision(3)} 份/h**`):r0(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(r0(`周余量 ${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:[m0(D1(G.reason))]})}if(z.state!=="ok"){if(W.push(m0(z.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),z.state==="network"&&z.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[m0(D1(z.reason))]});continue}let K=z.subscriptionType==="pro"?"Pro 20×":z.subscriptionType==="prolite"?"Pro 5×":z.subscriptionType==="plus"?"Plus 1×":z.subscriptionType??"套餐 MISS";W.push(r0(`${K} · 重置卡 ${z.resetCredits??"MISS"}`));let _=[[z.fiveHour,"5h"],[z.weekly,"周"]].flatMap(([L,j])=>L?[HZ(L,j)]:[]);if(_.length)W.push(xJ(_))}if(J>1)Y.push(r0(`${Q}/${J} 页 · ${Q<J?`下一页 codex-accounts ${Q+1}`:"首页 codex-accounts"}`));return Y}var Y5=4,bz,m0=($)=>({tag:"markdown",content:$}),r0=($)=>({tag:"markdown",content:`<font color='grey'>${D1($)}</font>`,text_size:"notation"});var H4=O(()=>{C0();bz={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 SJ($){let Z=new Map,J=$.map((G)=>{let K=G.fingerprint?Z.get(G.fingerprint):void 0;if(G.fingerprint&&!K)Z.set(G.fingerprint,G.account.name);return{...G,...K?{duplicateOf:K}:{}}}),Q=J.filter((G)=>!G.duplicateOf),V=(Q.length<=1||Q.every((G)=>G.fingerprint!==null))&&Q.every((G)=>G.usage.state==="ok"),X=Q.flatMap((G)=>G.usage.state==="ok"?[G.usage]:[]),H=V&&X.every((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent!==null))?X.filter((G)=>[G.fiveHour,G.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,z=V&&X.every((G)=>G.resetCredits!=null)?X.reduce((G,K)=>G+K.resetCredits,0):null,W=["fiveHour","weekly"].map((G)=>{let K=X.map((L)=>L[G]).filter((L)=>L!==null),_=V&&K.every((L)=>L.percent!==null&&L.percent>=0&&L.percent<=100);return{kind:G,count:K.length,remaining:_?K.reduce((L,j)=>L+(100-j.percent)/100,0):null}}).filter((G)=>G.count||!V);return{entries:J,complete:V,available:H,resetCredits:z,windows:W}}async function V5($){let Z=new Map,J=await Promise.all(y.list().map(async(Q)=>{let Y=null;try{Y=y.fingerprint(Q.id)}catch(z){return{account:Q,fingerprint:Y,usage:{state:"network",reason:`账号身份读取失败:${String(z)}`}}}let V=Y??Q.id,X=Z.get(V);if(!X)X=$?.id===Q.id?Promise.resolve($.usage):c2(Q.id),Z.set(V,X);let H=await X;if(H.state==="ok"&&H.accountFingerprint)Y=H.accountFingerprint;return{account:Q,usage:H,fingerprint:Y}}));return SJ(J)}var CJ=O(()=>{f0();T$()});import{homedir as mD}from"node:os";function cD($,Z=pD){return new Promise((J,Q)=>{let Y=setTimeout(()=>Q(Error(`timeout ${Z}ms`)),Z);$.then((V)=>{clearTimeout(Y),J(V)},(V)=>{clearTimeout(Y),Q(V)})})}function wz($){return typeof $==="string"&&uD.includes($)?$:null}async function X5($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (f2(),U6)),J=new Z({workDir:mD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Q)=>B(`Claude model catalog MISS: ${Q.message}`));try{let Q=await cD(J.listModels());if(!Q.length)throw Error("Claude SDK model catalog is empty");return Q.map((Y)=>({model:Y.model.replace(/^claude:/,""),display:Y.displayName,efforts:Y.supportedReasoningEfforts.map((V)=>V.reasoningEffort),defaultEffort:Y.defaultReasoningEffort}))}finally{await J.kill()}}async function yz($="default"){let Z=new H1({accountId:$});try{if(await Z.initialize("lodestar-models"),(await y1(()=>Z.request("account/read",{refreshToken:!1}),"账号查询"))?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Q=await y1(()=>Z.request("model/list",{}),"模型查询");if(!Array.isArray(Q?.data))throw Error("Codex model/list 缺少 data 数组");let Y=Q.data,V=[];for(let X of Y){if(!X||X.hidden||!X.id)continue;let H=(Array.isArray(X.supportedReasoningEfforts)?X.supportedReasoningEfforts:[]).map((W)=>wz(W?.reasoningEffort)).filter((W)=>W!==null);if(!H.length)continue;let z=wz(X.defaultReasoningEffort)??H[0];V.push({model:String(X.id),display:typeof X.displayName==="string"&&X.displayName?String(X.displayName):String(X.id),efforts:H,defaultEffort:z})}if(!V.length)throw Error("Codex model/list 未返回可用模型");return V}finally{await Z.close()}}async function vz($,Z){return(await U2($,Z)).map((Q)=>({model:Q,display:Q,efforts:z4,defaultEffort:"max"}))}var pD=1e4,uD,z4;var W4=O(()=>{w4();T$();h();uD=["none","minimal","low","medium","high","xhigh","max","ultra"];z4=["max","xhigh","high","medium","low"]});function Q0($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function p9($,Z){let J=$.agent==="claude"?c4.filter((Y)=>Y!=="default"):$.agent==="codex"?[...o4]:["off","minimal","low","medium","high","xhigh","max"],Q=Z.effort?.trim();return{efforts:J,defaultEffort:Q&&J.includes(Q)?Q:$.agent==="claude"?"max":$.agent==="codex"?"xhigh":"high"}}function H5($,Z){let J=$.modelSelection,Q=new Set(Q0(Z.hidden_models)),Y=[...new Set([...Q0(Z.custom_models),...J?[]:Q0(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},X=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.modelIds=[];try{await X()}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 H=$.models,z=(J?V.availableModels:H).map((G)=>({...G,origin:G.origin??"upstream"}));for(let G of Y){if(z.some((K)=>K.model.toLowerCase()===G.toLowerCase()))continue;z.push({model:G,display:G,origin:"custom",...p9($,Z)})}V.availableModels=z;let W=J?H.map((G)=>z.find((K)=>K.model===G.model)??{...G,origin:"upstream"}):z;$.models=[...W.filter((G)=>G.origin==="custom"||!Q.has(G.model)),...z.filter((G)=>G.origin==="custom"&&!W.some((K)=>K.model===G.model))],V.modelIds=$.models.map((G)=>G.model)},$}var U1=O(()=>{G0();J1()});import{existsSync as lD}from"node:fs";import{join as dD}from"node:path";function fz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function bJ($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(fz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(fz($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function hz($){return $===p||lD(dD(y.home($),"auth.json"))}var kJ=O(()=>{S0();e();T$();W4();h();f0();U1();j0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(V)=>{let X=hz(V),H=$.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,y.revision(V)]),enabled:X,models:[],modelCatalogState:{status:X?"idle":"disabled",updatedAt:Date.now()},defaultModel:H??"",async refreshModels(){if(W.enabled=hz(V),!W.enabled){W.models=[],W.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}W.modelCatalogState={status:"loading",updatedAt:null};try{if(W.models=await yz(V),z)for(let G of W.models)G.defaultEffort=z;if(!H)W.defaultModel=W.models[0]?.model??"";W.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(B(`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 K=h0(G);return Object.assign(K,g.codex.env),y.env(V,K)},resolveSpawnModel(G){return G},async readUsage(){return bJ(await c2(V))}};return W},Q=J(p);Q.forAccount=(V)=>{if(V===p)return Q;let X=y.revision(V),H=Z.get(V);if(H?.revision===X)return H.source;let z=H5(J(V),$);return Z.set(V,{revision:X,source:z}),z};let Y=Q.refreshModels.bind(Q);return Q.refreshModels=async()=>{await Promise.all([Y(),...y.list().filter((V)=>V.id!==p).map((V)=>Q.forAccount(V.id).refreshModels())])},Q}})});function w$($){let Z=new URL($);if(!["http:","https:"].includes(Z.protocol)||Z.username||Z.password||Z.search||Z.hash)throw Error("PackyAPI 地址必须是无凭据、查询参数和 fragment 的 HTTP(S) API 根地址");return Z.pathname=Z.pathname.replace(/\/+$/,"").replace(/\/v1$/,""),Z.toString().replace(/\/$/,"")}function G4($){let Z=w$($),J=new URL(Z);return J.protocol==="https:"&&!J.port&&J.pathname==="/"&&["cf.api.fan","slb-v1.api.fan","www.packyapi.ai"].includes(J.hostname)?iD:Z}function wJ($,Z){let J=w$($),Q=Q$("packy-models",J,Z),Y=z5.get(Q);if(Y)return Y;let V=A$(`${J}/v1/models`,Z,"PackyAPI models").then((X)=>{let H=new Set;return X.map((z)=>{if(typeof z.id!=="string"||!z.id.trim()||H.has(z.id)||!Array.isArray(z.supported_endpoint_types)||!z.supported_endpoint_types.length||!z.supported_endpoint_types.every((W)=>typeof W==="string"&&W))throw Error("PackyAPI 模型目录缺少有效 id/协议声明,或含重复模型");return H.add(z.id),{id:z.id,display:typeof z.name==="string"&&z.name?z.name:z.id,protocols:[...z.supported_endpoint_types],...k$(z.reasoning)?{reasoning:z.reasoning}:{}}})}).finally(()=>{if(z5.get(Q)===V)z5.delete(Q)});return z5.set(Q,V),V}function k$($){return $!==null&&typeof $==="object"&&!Array.isArray($)}async function G5($,Z,J={}){let Q=await X0($,{headers:{Accept:"application/json","Cache-Control":"no-cache","User-Agent":"Lodestar-Account-Balance/1.0",...J,...Z?{Authorization:`Bearer ${Z}`}:{}},redirect:"error",signal:AbortSignal.timeout(15000)}),Y=await Q.text(),V;try{V=JSON.parse(Y)}catch{throw new l$(Q.status,"响应不是有效 JSON",R$(Q.headers))}let X=k$(V)?V.code:void 0,H=X!==void 0&&![!0,0,200,"0","200"].some((z)=>z===X);if(!Q.ok||!k$(V)||V.success===!1||H||V.error!=null){let z=k$(V)&&k$(V.error)?V.error.message:k$(V)?V.message:null;throw new l$(Q.status,typeof z==="string"?z:"上游接口返回错误",R$(Q.headers))}return V}async function yJ($,Z,J,Q=!1){if(Z=Z.trim(),J=J.trim(),!Z||!/^[1-9]\d*$/.test(J)||!Number.isSafeInteger(Number(J)))return{state:"no_credentials",kind:"balance",windows:[],reason:"PackyAPI 真实余额需要系统访问令牌和正整数用户 ID;请配置 packy-balance-setup。"};let Y=w$($),V=Q$("packy-balance",Y,JSON.stringify([J,Z])),X=async()=>{try{let z=await G5(`${Y}/api/user/self`,Z,{"New-Api-User":J}),W=z.data;if(z.success!==!0||!k$(W)||W.id!==Number(J))throw Error("PackyAPI 账户响应缺少成功状态,或用户 ID 与余额凭据不匹配");if(typeof W.quota!=="number"||!Number.isSafeInteger(W.quota))throw Error("PackyAPI 账户余额 quota 缺失或无效");let G=(await G5(`${Y}/api/status`)).data;if(!k$(G)||typeof G.quota_per_unit!=="number"||!Number.isFinite(G.quota_per_unit)||G.quota_per_unit<=0||G.quota_display_type!=="USD")throw Error("PackyAPI 账户余额单位缺失或不是已支持的 USD 单位");let K=W.quota/G.quota_per_unit;if(!Number.isFinite(K))throw Error("PackyAPI 账户余额换算结果无效");return{state:"ok",kind:"balance",windows:[],fetchedAt:Date.now(),balance:{remaining:K,currency:"USD"}}}catch(z){let W=w0(z,[Z]);return B(`PackyAPI balance MISS: ${W}`),{state:z instanceof l$&&[401,403].includes(z.status)?"no_credentials":z instanceof l$&&z.status===429?"rate_limited":"network",kind:"balance",windows:[],reason:W,...z instanceof l$&&z.retryAfterMs!==void 0?{retryAfterMs:z.retryAfterMs}:{}}}};if(!Q)return W5.read(V,X);let H=await X();if(H.state==="ok")W5.prime(V,H);else W5.invalidate(V);return H}async function Iz($,Z){if(!Z)return{state:"no_credentials",kind:"quota",windows:[]};let J=G4($);return W5.read(Q$("packy",J,Z),async()=>{try{let Y=(await G5(`${J}/api/usage/token/`,Z)).data;if(!k$(Y)||typeof Y.unlimited_quota!=="boolean")throw Error("PackyAPI 令牌配额响应缺少 unlimited_quota");if(Y.unlimited_quota)return{state:"not_applicable",kind:"balance",windows:[],reason:"此 API key 为无限额度令牌;令牌接口不提供账户余额,需要系统访问令牌查询。"};let{total_available:V,total_granted:X}=Y;if(typeof V!=="number"||!Number.isFinite(V)||typeof X!=="number"||!Number.isFinite(X)||X<0)throw Error("PackyAPI 令牌配额数值缺失或无效");let H=(await G5(`${J}/api/status`)).data;if(!k$(H)||typeof H.quota_per_unit!=="number"||!Number.isFinite(H.quota_per_unit)||H.quota_per_unit<=0||H.quota_display_type!=="USD")throw Error("PackyAPI 配额单位缺失或不是已支持的 USD 额度单位");return{state:"ok",kind:"quota",windows:[],fetchedAt:Date.now(),quota:{remaining:V/H.quota_per_unit,limit:X/H.quota_per_unit,currency:"USD"}}}catch(Q){let Y=w0(Q,[Z]);return B(`PackyAPI quota MISS: ${Y}`),{state:Q instanceof l$&&[401,403].includes(Q.status)?"no_credentials":Q instanceof l$&&Q.status===429?"rate_limited":"network",kind:"quota",windows:[],reason:Y,...Q instanceof l$&&Q.retryAfterMs!==void 0?{retryAfterMs:Q.retryAfterMs}:{}}}})}var r1="https://cf.api.fan",iD="https://www.packyapi.ai",z5,l$,W5;var vJ=O(()=>{u0();P2();m$();h();z5=new Map;l$=class l$ extends Error{status;retryAfterMs;constructor($,Z,J){super(`PackyAPI HTTP ${$}: ${Z}`);this.status=$;this.retryAfterMs=J}};W5=new n0});function gz($){return _5.find((Z)=>Z.other===$)?.id??$}function mz($){let Z=_5.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function c9($){let Z=$.api_key?.trim(),J=$.auth_token?.trim();if(Z&&J&&Z!==J)throw Error("同一账号的 api_key 与 auth_token 不一致,请重新配置");return Z||J}function B5($,Z){if($.id==="packy")return w$(Z);let J=new URL(Z);if(!["http:","https:"].includes(J.protocol)||J.username||J.password||J.search||J.hash)throw Error(`${$.id} 接口地址必须是无凭据、查询参数和 fragment 的 HTTP(S) 地址`);if($.id==="glm")return k4(`${J.origin}/api/anthropic`);if(J.pathname=J.pathname.replace(/\/+$/,""),J.hostname==="api.deepseek.com"&&["/","/v1"].includes(J.pathname))J.pathname="/anthropic";return J.toString().replace(/\/+$/,"")}function K5($,Z){let J=B5($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function K4($){let{api_key:Z,auth_token:J,base_url:Q,...Y}=$;return Y}function fJ($,Z,J={}){let Q=Z[$.id]??{},Y=Z[$.other]??{},V=c9(Q),X=c9(Y),H=Q.base_url?.trim(),z=Y.base_url?.trim();if(V&&X&&V!==X||H&&z&&K5($,H)!==K5($,z))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:B5($,H||z||$.base)};let W=J[$.id]??J[$.other]??{};if(c9(W)&&(H||z)&&W.base_url&&K5($,H||z)!==K5($,W.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:c9(W),base:B5($,H||z||W.base_url||$.base)}}function u9($,Z={}){let J={...$};for(let Q of _5){let{key:Y,base:V}=fJ(Q,$,Z);J[Q.id]={...K4($[Q.id]??{}),base_url:V,...Q.id==="glm"?{auth_token:Y??""}:{api_key:Y??""}},J[Q.other]={...K4($[Q.other]??{}),api_key:Y??"",base_url:Q.id==="glm"?`${new URL(V).origin}/api/coding/paas/v4`:Q.id==="deepseek"?V.replace(/\/anthropic$/,""):V}}return nD(J),J}function nD($){let Z=new Set(["packy","packy-secondary","packy-codex"]),J=new Set,Q=new Set,Y=(X)=>!!(X.management_token?.trim()||X.management_user_id?.trim()||X.management_url?.trim()),V=(X)=>{if(Q.has(X))throw Error(`PackyAPI 余额账号引用循环:${X}`);if(J.has(X))return $[X];Q.add(X);let H=$[X]??{},z=H.billing_source?.trim(),W=z||(X==="packy-codex"&&!Y(H)?"packy":void 0);if(W){if(!Z.has(W)||!$[W])throw Error(`PackyAPI 余额账号引用不存在:${W}`);if(z&&Y(H))throw Error(`PackyAPI ${X} 不能同时配置 billing_source 和独立余额凭据`);let G=V(W);$[X]={...H,...z||Y(G)||G.billing_source?{billing_source:W,management_token:G.management_token,management_user_id:G.management_user_id,management_url:G.management_url||G4(G.base_url||r1)}:{}}}return Q.delete(X),J.add(X),$[X]??H};for(let X of Z)if($[X])V(X)}function hJ($,Z,J){let Q=Object.fromEntries(Object.entries(J).filter(([,z])=>z!==void 0)),Y={...$,[Z]:{...$[Z],...Q}},V=_5.find((z)=>z.id===Z||z.other===Z);if(!V)return{[Z]:Y[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,H=J.base_url!==void 0;if(X||H){let z=$[Z]??{},W=$[V.id]??{},G=$[V.other]??{},K=X?c9(J):fJ(V,$).key,_=B5(V,J.base_url?.trim()||z.base_url||W.base_url||G.base_url||V.base);Y[V.id]={...K4(Y[V.id]??{}),base_url:_,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Y[V.other]=K4(Y[V.other]??{})}else{let{key:z,base:W}=fJ(V,Y);Y[V.id]={...K4(Y[V.id]??{}),base_url:W,...V.id==="glm"?{auth_token:z??""}:{api_key:z??""}},Y[V.other]=K4(Y[V.other]??{})}return{[V.id]:Y[V.id],[V.other]:Y[V.other]}}var _5;var l9=O(()=>{w4();vJ();_5=[{id:"deepseek",other:"deepseek-harness",base:"https://api.deepseek.com/anthropic"},{id:"glm",other:"dsh-glm",base:"https://open.bigmodel.cn/api/anthropic"},{id:"packy",other:"packy-codex",base:"https://cf.api.fan"}]});function IJ(){return JSON.stringify([A6(),DX(),J$().map(($)=>[$.id,$.enabled,$.spawnRevision,$.usageAccount]),y.list().map(($)=>[$.id,$.name,$.revision])])}function gJ(){return i9&&i9.key===IJ()&&Date.now()<i9.until?i9.rows:void 0}function pz(){let $=gJ();if($)return Promise.resolve($);let Z=IJ();if(d9?.key===Z)return d9.promise;let J=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],Q=(z)=>J.includes(z)?J.indexOf(z):J.length,Y=J$().filter((z)=>z.enabled||z.kind==="codex-subscription"&&y.list().some((W)=>W.id!=="default")).sort((z,W)=>Q(z.id)-Q(W.id)),V=new Set,X=[];for(let z of Y){if(z.kind==="codex-subscription"){X.push(V5().then((K)=>K.entries.filter((_)=>!_.duplicateOf).map((_)=>({id:`codex:${_.account.id}`,label:`Codex·${_.account.name}`,usage:bJ(_.usage)}))));continue}let W=z.usageAccount?.id??gz(z.id);if(V.has(W))continue;V.add(W);let G=z.usageAccount?.label??(W==="glm"?"GLM Coding Plan":W==="deepseek"?"DeepSeek":z.kind==="claude-subscription"?"Claude 订阅":z.display);X.push(Promise.resolve().then(()=>z.readUsage()).catch((K)=>{let _=K instanceof Error?K.message:String(K);return B(`account usage ${W} MISS: ${_}`),{state:"network",windows:[],reason:_}}).then((K)=>[{id:W,label:G,usage:K}]))}let H=Promise.all(X).then((z)=>{let W=z.flat(),G=Date.now(),K=Math.min(G+X1,...W.map((_)=>(_.usage.fetchedAt??G)+X1));if(Z===IJ())i9={key:Z,rows:W,until:K};return W}).finally(()=>{if(d9?.promise===H)d9=void 0});return d9={key:Z,promise:H},H}var i9,d9;var cz=O(()=>{f0();CJ();kJ();e();l9();T$();m$();h()});import{homedir as aD}from"node:os";function L5($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function j5($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!L5($))throw Error(`Claude ${J}格式无效`);let Q=$.utilization;if(Q!==null&&(typeof Q!=="number"||!Number.isFinite(Q)||Q<0||Q>100))throw Error(`Claude ${J} utilization 缺失或无效`);let Y=$.resets_at;if(Y!==null&&(typeof Y!=="string"||!Number.isFinite(Date.parse(Y))))throw Error(`Claude ${J} resets_at 缺失或无效`);return{kind:Z,label:J,percent:Q,resetsAt:Y===null?null:new Date(Y)}}function lz($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function dz($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=lz(e4(Z.trim()));if(!J||J==="default")return null;let Q=$.windows.filter((Y)=>{let V=Y.kind.startsWith("modelWeekly:")?Y.kind.slice(12):Y.kind==="seven_day_opus"?"opus":Y.kind==="seven_day_sonnet"?"sonnet":null;return V!==null&&lz(V)===J});if(Q.length>1)return B(`Claude weekly usage MISS: ${Z} 匹配多个模型专属周额度窗口`),null;if(Q.length===1)return Q[0];return $.windows.find((Y)=>Y.kind==="weekly")??null}function sD($){if(!L5($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!L5($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[j5(Z.five_hour,"fiveHour","5h 窗口"),j5(Z.seven_day,"weekly","周额度")],Q=Z.five_hour!=null||Z.seven_day!=null;for(let[Y,V]of[["seven_day_oauth_apps","OAuth 应用周额度"],["seven_day_opus","Opus 周额度"],["seven_day_sonnet","Sonnet 周额度"]]){if(Z[Y]==null)continue;J.push(j5(Z[Y],Y,V)),Q=!0}if(Z.model_scoped!=null){if(!Array.isArray(Z.model_scoped))throw Error("Claude 模型专属额度 model_scoped 格式无效");for(let Y of Z.model_scoped){if(!L5(Y)||typeof Y.display_name!=="string"||!Y.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Y.display_name.trim();J.push(j5(Y,`modelWeekly:${V}`,`${V} 周额度`)),Q=!0}}if(!Q)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function iz($){return oD.read("claude-subscription",()=>tD($))}async function tD($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (f2(),U6)),J=new Z({workDir:aD(),effort:"default",allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(V)=>B(`Claude subscription usage MISS: ${V.message}`));let Q,Y;try{let V=await Promise.race([J.readSubscriptionUsage(),new Promise((X,H)=>{Q=setTimeout(()=>H(Error(`Claude 订阅额度查询超时(${uz/1000}s)`)),uz)})]);return sD(V)}catch(V){throw Y=V instanceof Error?V:Error(String(V)),Y}finally{clearTimeout(Q);try{await J.kill()}catch(V){if(Y)throw AggregateError([Y,V],`${Y.message};额度查询进程关闭失败:${V instanceof Error?V.message:String(V)}`);throw V}}}catch(Z){let J=Z instanceof Error?Z.message:String(Z);return B(`claude-sub readUsage MISS: ${J}`),{state:Z?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING"?"no_credentials":m2(Z)?"rate_limited":"network",windows:[],reason:J}}}var uz=30000,oD;var mJ=O(()=>{h();B6();m$();oD=new n0});function nz($){let Z=[];for(let J of $.matchAll(rD)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function q5($,Z=process.platform){if(Z!=="win32")return $;let J=eD.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var rD,eD;var pJ=O(()=>{rD=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;eD=/^\/([a-zA-Z])\//});function sz($){if(az.test($))return{marker:"start",body:$.replace(az,"")};if(oz.test($))return{marker:"end",body:$.replace(oz,"")};return{marker:"none",body:$}}var az,oz;var tz=O(()=>{az=/^>{3,}[ \t]?/,oz=/^<{3,}[ \t]?/});async function rz($,Z,J,Q,Y){let{marker:V,body:X}=sz(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)uJ($,"reopen");return $.multiMsgBuffer=[],cJ($,X,J,Q,Y),!0}if(V==="end"){if($.multiMsgBuffer===null){if(X.trim()||J.length)return!1;return B(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}cJ($,X,J,Q,Y);let{multiMsgBuffer:H,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await ZU($,H,z),!0}if($.multiMsgBuffer!==null)return cJ($,Z,J,Q,Y),!0;return!1}function cJ($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)$U($,Y)}function $U($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await t0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else k0(Z,J)})()}async function ZU($,Z,J){for(let[X,H]of J)if(H)k0(X,H);let Q=Z.filter((X)=>X.text.trim()||X.files.length);if(Q.length===0){B(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await S($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((z)=>`[file: ${z}]`).join(" ")+`
222
222
  `:"")+X.text}).join(`
223
223
 
224
- `),V=Y[Y.length-1];B(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],V.userOpenId,V.msgId)}function kJ($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;B(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)k0(Y,Q);d0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var gz=O(()=>{r();f();hz()});import{mkdtemp as wD,rm as vD,writeFile as fD}from"node:fs/promises";import{createRequire as hD}from"node:module";import{tmpdir as ID}from"node:os";import{join as mz}from"node:path";function iD($){let Z=lz.get($);if(Z)return Z;let{liteAdaptor:J}=n1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=n1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=n1("mathjax-full/js/mathjax.js"),{TeX:V}=n1("mathjax-full/js/input/tex.js"),{AllPackages:X}=n1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:H}=n1("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Y(z);let G=Q.document("",{InputJax:new V({packages:X}),OutputJax:new H({fontCache:"none"})}),W={adaptor:z,doc:G};return lz.set($,W),W}function dz($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function nD($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function aD($,Z=vJ,J=!0){try{let Y=Z*gD,{adaptor:Q,doc:V}=iD(Z),X=V.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),H=Q.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(H)){let B0=H.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(B0)}let z=H.indexOf("<svg"),G=H.lastIndexOf("</svg>");if(z<0||G<0)throw Error("MathJax returned no SVG");let W=H.slice(z,G+6),K=W.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let _=dz(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),L=dz(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),j=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!j)throw Error("MathJax SVG missing viewBox");let q=j.trim().split(/[\s,]+/).map(Number);if(q.length!==4||q.some((B0)=>!Number.isFinite(B0))||q[2]<=0||q[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[F,R,D,U]=q,A=/<text\b/.test(W)?lD:0,x=`${F} ${R} ${D+A} ${U}`,S=_*Y,h=A*(S/D),y=Math.max(1,Math.ceil(S+h)),g=Math.max(1,Math.ceil(L*Y)),C=mD-yJ*2,I=Math.min(1,C/y),c=Math.max(1,Math.round(y*I)),l=Math.max(1,Math.round(g*I));if(I<1&&l<pD)throw Error(`formula would be unreadable after width cap (${c}x${l})`);let M=c+yJ*2,b=l+cz*2,d=W.slice(K.length,-6).replace(/currentColor/g,pz).replace(/font-family="serif"/g,`font-family="${dD}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${M}" height="${b}" viewBox="0 0 ${M} ${b}" style="color:${pz}">`,`<rect x="0" y="0" width="${M}" height="${b}" rx="6" fill="${oz}"/>`,`<svg x="${yJ}" y="${cz}" width="${c}" height="${l}" viewBox="${nD(x)}" preserveAspectRatio="xMidYMid meet">`,d,"</svg>","</svg>"].join(""),width:M,height:b}}catch(Y){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function oD($,Z=vJ,J=!0){let Y=aD($,Z,J);if(!Y)return null;try{let{Resvg:Q}=n1("@resvg/resvg-js"),X=new Q(Y.svg,{background:oz,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:uz,sansSerifFamily:uz}}).render().asPng(),H=new DataView(X.buffer,X.byteOffset,X.byteLength),z=H.getUint32(16),G=H.getUint32(20);if(z!==Y.width||G!==Y.height)throw Error(`PNG dimensions ${z}x${G} != SVG ${Y.width}x${Y.height}`);return{png:X,width:z,height:G}}catch(Q){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function sD($){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 iz($,Z){let J=[],Y=(W,K,_)=>{let L=W[0],j=K.trim();if(!j)return;J.push({start:Z+W.index,end:Z+W.index+L.length,tex:j,raw:L,display:_})},Q,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=V.exec($))!==null)Y(Q,Q[1]??Q[2]??"",!0);let X=/\\\(([\s\S]+?)\\\)/g;while((Q=X.exec($))!==null)Y(Q,Q[1]??"",!1);let H=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=H.exec($))!==null){let W=(Q[1]??"").trim();if(sD(W))Y(Q,W,!1)}J.sort((W,K)=>W.start-K.start||K.end-W.end);let z=[],G=-1;for(let W of J){if(W.start<G)continue;z.push(W),G=W.end}return z}function sz($){let Z=p5($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...iz($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...iz($.slice(Y),Y));return J}function tD($){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(nz[Y])return nz[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 ZM($){let Z=az.get($);if(Z!==void 0)return Z;return Z=eD++,az.set($,Z),Z}function JM($,Z){return`${uD}\x00${ZM(Z)}\x00${$}`}function YM($){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 QM($,Z){let J=JM($,Z),Y=i1.get(J);if(Y)return Y;let Q=wJ.get(J);if(Q)return Q;let V=(async()=>{let X=oD($,vJ,!0);if(!X)return null;let H=null;try{H=await wD(mz(ID(),"lodestar-math-"));let z=mz(H,`formula-${YM($)}.png`);await fD(z,X.png);let G=await Z(z,{tex:$,width:X.width,height:X.height});if(!G)return B(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let W={key:G,width:X.width,height:X.height};if(i1.has(J))i1.delete(J);i1.set(J,W);while(i1.size>$M){let K=i1.keys().next().value;if(typeof K!=="string")break;i1.delete(K)}return W}catch(z){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(H)try{await vD(H,{recursive:!0,force:!0})}catch(z){B(`math-render: temp cleanup failed for ${H}: ${z}`)}}})();wJ.set(J,V);try{return await V}finally{wJ.delete(J)}}function VM($,Z,J){let Y=$.width<=cD;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 tz($,Z={}){let J=sz($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??rD,Q=await Promise.all(J.map(async(W)=>{if(!W.display){let K=tD(W.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await QM(W.tex,Y)}})),V=[],X="",H=0,z=0,G=()=>{if(!X)return;if(X.trim())V.push({type:"markdown",text:X});X=""};for(let W=0;W<J.length;W++){let K=J[W],_=Q[W];if(X+=$.slice(H,K.start),_.unicode!==null){X+=_.unicode,H=K.end;continue}let L=_.uploaded;if(!L){X+=K.raw,H=K.end;continue}G(),V.push(VM(L,K,z++)),H=K.end}if(X+=$.slice(H),G(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function fJ($){return sz($).length>0}var n1,gD=0.5,vJ=22,pz="#1F2329",oz="#F7F8FA",yJ=12,cz=8,mD=720,pD=14,cD=278,uD="v4-native-cjk-tail-pad",lD=1100,uz,dD="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",lz,nz,rD=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (r(),J0));return Z($)},az,eD=1,i1,wJ,$M=512;var rz=O(()=>{f();n1=hD(import.meta.url),uz=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",lz=new Map;nz={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:"Ω"};az=new WeakMap,i1=new Map,wJ=new Map});import{readFileSync as HM}from"node:fs";function X4($){return hJ.has($)}function I9($){hJ.add($)}function g9($){hJ.delete($)}function H4(){try{let $={};for(let[Z,J]of n0)$[Z]=J;o(X7,$)}catch($){throw B(`notify-callbacks: save failed (${X7}): ${$}`),$}}function JG(){let $=[],Z;try{Z=HM(X7,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-ZG,Q=0,V=0;for(let X of Object.values(J)){if(!X||typeof X!=="object")continue;if(typeof X.notifyId!=="string"||typeof X.callbackUrl!=="string")continue;if(typeof X.createdAt!=="number"||X.createdAt<Y){Q++;continue}if(X.replyState?.status==="sending"&&!X.resolvedAt&&!X.unknownAt)X.unknownAt=Date.now(),X.unknownBy={openId:X.replyState.openId},X.unknownReason="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",V++;if(n0.set(X.notifyId,X),X.replyState?.status==="sending"&&X.unknownAt)$.push(X)}if(B(`notify-callbacks: loaded ${n0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),V)B(`notify-callbacks: ${V} interrupted text reply(s) marked UNKNOWN`);if(Q>0||V>0)H4()}catch(J){B(`notify-callbacks: load failed (${X7}): ${J}`)}return $}function YG($){let Z=Date.now();if(Z-$G>=zM)GM(Z),$G=Z;n0.set($.notifyId,$),H4()}function h$($){return n0.get($)}function IJ($){return[...n0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function m9($,Z){if(!$)return;return IJ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function QG($,Z){return!!Z&&[...n0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function z4($,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{H4()}catch(V){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw V}}function p9($,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{H4()}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 gJ($,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,H4()}function H7($,Z,J){try{return p9($,Z,J),{state:"complete"}}catch(Y){let V=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{gJ($,Z,J,V)}catch(X){let H=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${H}`;let z=n0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function GM($=Date.now()){let Z=$-ZG,J=0;for(let[Y,Q]of n0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)n0.delete(Y),J++;if(J>0)H4();return J}async function mJ($,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(),ez);try{let X=await PQ($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Y),signal:Q.signal});if(X.status>=200&&X.status<300){let z;try{let G=(await X.text()).trim();if(G.startsWith("{")){let W=JSON.parse(G),K=typeof W?.text==="string"?W.text:typeof W?.reply==="string"?W.reply:typeof W?.message==="string"?W.message:"";if(K.trim())z=K.trim().slice(0,500)}else if(G)z=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:z}}let H="";try{H=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${H?` ${H}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${ez}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function VG($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((H)=>H.id===Y):void 0,V=$.replyState?.response,X=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?{...X,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...X,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var ZG=604800000,ez=2500,n0,$G,zM=86400000,hJ,X7;var c9=O(()=>{o0();f();Q0();x0();n0=new Map,$G=Date.now(),hJ=new Set;X7=YQ});function z7($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function G4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(m9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(z7($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function pJ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:m9($.chatId)?"notification":z7($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function cJ($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||G4($,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()??"",X=V.length>40?V.slice(0,40)+"…":V,H=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(v0(Y.cardId),await n8(Y.cardId,{config:{summary:{content:H}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||G4($,Z))return;await m1(Y.messageId,[Y.userOpenId])})().catch((z)=>B(`session "${$.sessionName}": question notification failed: ${z}`))}function G7($){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=pJ($,J);if(V.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;Y0(Z.cardId,T.tool(Q.i),I2(Q.i,J,Y.questions,"\uD83E\uDD14",V)),cJ($,J)}}function XG($){return z7($)!==void 0}async function HG($,Z,J,Y){let Q=z7($);if(!Q){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[V,X]=Q,H=G4($,V);if(H){let G=`${H}。这条文字未提交,请稍后重新发送。`;if(!await E($.chatId,G))throw Error(`提问等待提示发送失败: ${G}`);return}if(await uJ($,V,X.currentIdx,Z,J)&&Y)d0(Y,"CheckMark")}async function zG($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return B(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==V.currentIdx)return B(`session "${$.sessionName}": stale ask click q=${J} current=${V.currentIdx}`),!1;return GG($,Z,{optionIdx:Y,user:Q})}async function uJ($,Z,J,Y,Q){let V=$.pendingAsks.get(Z);if(!V)return B(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let X=(Y??"").trim();if(!X)return B(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==V.currentIdx)return B(`session "${$.sessionName}": stale ask custom q=${J} current=${V.currentIdx}`),!1;return GG($,Z,{customText:X,user:Q})}function GG($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=G4($,Z);if(Q)return B(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let V=Y.currentIdx,X=Y.questions[V];if(!X)return B(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let H;if(J.customText!==void 0)H=J.customText;else if(J.optionIdx!==void 0){let _=X.options?.[J.optionIdx];if(!_)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;H=_.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[X.question]=H,Y.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Y.questions.length,G=void 0;for(let _=V+1;_<z;_++)if(!Y.answered.has(_)){G=_;break}Y.currentIdx=G;let W=$.currentTurn,K=W?.toolByUseId.get(Z);if(W&&K){let _=I2(K.i,Z,Y.questions,G===void 0?"✅":"\uD83E\uDD14",{currentIdx:G,answered:Y.answered});Y0(W.cardId,T.tool(K.i),_)}if(G===void 0)if(Y.requestId)lJ($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),G7($);return!0}function lJ($,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),G7($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var W7=O(()=>{f$();Q$();r();f();c9()});import{isAbsolute as KM}from"node:path";function T0($){if($?.planLiveInserted)return T.planLive;return $?.taskLiveInserted?T.taskBoardLive:T.footer}function BM($){return $==="ImageGeneration"||$==="imageGeneration"}function _M($,Z,J){if(J||!BM($))return null;let Y=V7(Z.trim());return KM(Y)?Y:null}function jM($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function WG($,Z,J){return $==="read"?z9(Z,J):H9(Z,J)}function KG($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=jM(J);if(Q&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(z);if(G&&G.kind===Q){let W=G.items.length;G.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:z,name:J,input:Y,batchSlot:W});let K=Q==="read"?z9(z,G.items):H9(z,G.items);Y0($.currentTurn.cardId,T.tool(z),K),K7($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let V=w1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,U0(z.cardId,v1($.taskBoard),{type:"insert_before",targetElementId:T.footer});else Y0(z.cardId,T.taskBoardLive,v1($.taskBoard));let G=V==="TaskCreate";if(G)z.taskUpdateI=null;else z.taskCreateI=null;let W=(G?z.taskCreateI:z.taskUpdateI)===null;if(W)if(G)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let K=G?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:K,name:J,input:Y});let _=V1(K,$.taskBoard,{name:V,status:"⏳"});W?U0(z.cardId,_,{type:"insert_before",targetElementId:T0(z)}):Y0(z.cardId,T.tool(K),_),K7(z,J,Y);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Q){$.currentTurn.openBatchI=X;let z=[{toolUseId:Z,input:Y,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Q,items:z}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Y,batchSlot:0});let G=Q==="read"?z9(X,z):H9(X,z);U0($.currentTurn.cardId,G,{type:"insert_before",targetElementId:T0($.currentTurn)}),K7($.currentTurn,J,Y);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Y}),J==="AskUserQuestion"){let z=Array.isArray(Y?.questions)?Y.questions:[],G=z.length>0?0:void 0,W=new Map;$.pendingAsks.set(Z,{questions:z,i:X,answers:{},answered:W,currentIdx:G});let K=I2(X,Z,z,"\uD83E\uDD14",pJ($,Z));U0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:T0($.currentTurn)}),cJ($,Z);return}let H=O$(X,J,Y,null,"⏳");U0($.currentTurn.cardId,H,{type:"insert_before",targetElementId:T0($.currentTurn)}),K7($.currentTurn,J,Y)}function K7($,Z,J){if(!$)return;let Y=e$(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,V=S1(Z),X=Q?`\uD83D\uDD27 ${V}: ${Q}`:`\uD83D\uDD27 ${V}`;Z4($.cardId,X)}function BG($,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(([,W])=>W!==void 0))};let X=typeof J==="string"?J:Array.isArray(J)?J.map((W)=>W?.text??JSON.stringify(W)).join(`
225
- `):JSON.stringify(J);if(V.output=X,V.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=_M(V.name,X,Y);if(H){LM($,$.currentTurn,V,H),a1($);return}if(V.name==="AskUserQuestion"){a1($);return}if(V.batchSlot!=null){let W=$.currentTurn.toolBatches.get(V.i);if(W){let K=W.items[V.batchSlot];if(K)K.output=X,K.isError=Y;let _=WG(W.kind,V.i,W.items);Y0($.currentTurn.cardId,T.tool(V.i),_)}a1($);return}let z=w1(V.name);if(z){PM($,V,z,V.input,X,Y,V.resolvedNote);return}let G=O$(V.i,V.name,V.input,X,Y?"❌":"✅",V.resolvedNote);Y0($.currentTurn.cardId,T.tool(V.i),G),a1($)}function LM($,Z,J,Y){if(Z.outboundSeenPaths.has(Y))return;Z.outboundSeenPaths.add(Y);let Q=Z.cardId,V=T.tool(J.i),X=Z.imageDeliveryInflight??=new Map,H=X.get(Q)??new Set;X.set(Q,H);let z=(async()=>{let G=null;try{G=await BJ(Y)}catch(K){B(`generated image upload failed: ${K}`)}if(G){let K=!1;try{K=await A0(Q,V,O$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,G),{notifyCardFailure:!1})}catch(_){B(`generated image embed failed: ${_}`)}if(K){J.imageKey=G,Z.outboundSentPaths.add(Y);return}B(`generated image could not be embedded in card ${Q}; sending it as a separate message`)}let W=G?await d8($.chatId,G)!==null:await T9($.chatId,Y);if(W)Z.outboundSentPaths.add(Y);else B(`generated image delivery failed: ${Y}`);if(J.resolvedNote=W?"图片已单独发送。":"图片发送失败。",await A0(Q,V,O$(J.i,J.name,J.input,J.output??null,W?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!W&&G)await E($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(G)=>{B(`generated image delivery failed: ${G}`),await E($.chatId,`❌ 生成图片发送失败:${G instanceof Error?G.message:String(G)}`)});H.add(z),z.finally(()=>{if(H.delete(z),!H.size)X.delete(Q)}).catch((G)=>B(`generated image failure notice failed: ${G}`))}async function dJ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Y)=>[...Y]);await Promise.allSettled(J)}function PM($,Z,J,Y,Q,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=UZ($.taskBoard,J,Y,Q);let H=V1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(Y0($.currentTurn.cardId,T.tool(Z.i),H),$.currentTurn.taskLiveInserted)Y0($.currentTurn.cardId,T.taskBoardLive,v1($.taskBoard));a1($)}function a1($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function iJ($,Z,J,Y,Q,V=$.currentTurn){let X=V;if(!X)return;for(let[H,z]of Y){if(X.toolByUseId.has(H))continue;let G=z.batchSlot??null,W=z.input,K,_;if(G!=null){let D=Q.get(z.i)?.items[G];if(!D)continue;W=D.input,K=D.output,_=D.isError}else K=z.output??null,_=z.isError??!1;let L=K!=null,j=e2(Z,T.tool(z.i));if(L&&!j)continue;if(G!=null){let D=Q.get(z.i)?.kind;if(!D)continue;let U=X.toolCount++,A={toolUseId:H,input:W,output:K,isError:_};X.toolBatches.set(U,{kind:D,items:[A]}),X.toolByUseId.set(H,{...z,i:U,batchSlot:0}),U0(J,WG(D,U,[A]),{type:"insert_before",targetElementId:T0(X)});continue}let q=w1(z.name);if(q){let D=q==="TaskCreate";if(D)X.taskUpdateI=null;else X.taskCreateI=null;let U=(D?X.taskCreateI:X.taskUpdateI)===null;if(U)if(D)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let A=D?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(H,{...z,i:A});let x=!L?"⏳":_?"❌":"✅",S=V1(A,$.taskBoard,{name:q,status:x},z.resolvedNote);U?U0(J,S,{type:"insert_before",targetElementId:T0(X)}):Y0(J,T.tool(A),S);continue}let F=X.toolCount++;X.toolByUseId.set(H,{...z,i:F});let R=!L?"⏳":_?"❌":"✅";U0(J,O$(F,z.name,z.input,K,R,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:T0(X)})}}var _G=O(()=>{CJ();f$();Q$();r();f();W7()});async function jG($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return B(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let V=$.proc;if(!V)return B(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let X=J==="deny"?"deny":"allow";try{V.sendPermissionResponse(Z,X,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(G){return B(`session "${$.sessionName}": permission response ${Z} failed: ${G}`),{ok:!1,message:`权限决定发送失败: ${G instanceof Error?G.message:G}`}}$.pendingPermissions.delete(Z);let H=$.currentTurn,z=H?.toolByUseId.get(Q.toolUseId);if(H&&z){let G=w1(z.name);if(J==="deny"){let W=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,K=G?V1(z.i,$.taskBoard,{name:G,status:"❌"},W):O$(z.i,z.name,z.input,W,"❌");Y0(H.cardId,T.tool(z.i),K)}else{let W=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${W}** by ${Y||"匿名"}`;let K=G?V1(z.i,$.taskBoard,{name:G,status:"⏳"},z.resolvedNote):O$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);Y0(H.cardId,T.tool(z.i),K)}}if(B(`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 LG($,Z){let J=$.currentTurn;if(!J){B(`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){B(`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){B(`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 X=$.pendingAsks.get(Y);if(!X){B(`session "${$.sessionName}": AskUserQuestion ${Y} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(X.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Y}),X.currentIdx===void 0)lJ($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),B(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let V=o6(Q.i,Q.name,Q.input,Z.request_id);if(Y0(J.cardId,T.tool(Q.i),V),J.userOpenId&&J.messageId){let X=e$(Q.name,Q.input),H=S1(Q.name),z=X&&X.length>30?X.slice(0,30)+"…":X,G=z?`\uD83D\uDD10 等审批: ${H} · ${z}`:`\uD83D\uDD10 等审批: ${H}`;(async()=>{v0(J.cardId),await n8(J.cardId,{config:{summary:{content:G}}}),await m1(J.messageId,[J.userOpenId])})()}}var PG=O(()=>{f$();Q$();r();f();W7()});async function qG($=(Z)=>new r$({accountId:Z})){if(O2(m))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Y;try{Z=$(m),await Z.initialize("lodestar-login-check"),Y=await E1(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Q){J=Error(`默认账号登录检查失败:${W4(Q).message}`,{cause:Q})}if(!J){if(Y?.account===null||Y?.account?.type==="apiKey")J=Error("默认账号未登录 ChatGPT,请先发送不带备注的 codex-login 完成登录,再添加额外账号。");else if(Y?.account?.type!=="chatgpt")J=Error("默认账号登录检查失败:account/read 返回的账号状态无效")}if(Z)try{if(await Z.close(),Z.isAlive())throw Error("检查进程仍未退出")}catch(Q){J=Error([J?.message,`默认账号检查进程关闭失败:${W4(Q).message}`].filter(Boolean).join(";"),{cause:Q})}if(J)throw J}class FG{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Q)=>new r$({accountId:Q,login:!0}),Z=900000,J=(Q,V)=>{k.recordLogin(Q,V),f2(Q)},Y=1e4){this.createClient=$;this.waitMs=Z;this.recordLogin=J;this.stateWaitMs=Y}async start($,Z){if(this.stopping)throw Error("服务正在退出,无法开始登录");if(!Z.userOpenId)throw Error("无法确认登录发起者");if(this.attempts.has($))throw Error("该账号已有登录任务;使用 codex-login-cancel 取消后再登录");let J=BV($),Y;try{Y=this.createClient($)}catch(z){throw J(),z}let Q,V,X=new Promise((z,G)=>{Q=z,V=G});X.catch(()=>{});let H={owner:Z,client:Y,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:X,resolve:Q,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};H.notification=(z,G)=>{if(H.finishing||!H.loginRequested)return;if(z==="account/updated"){if(G?.authMode==="chatgpt"){if(H.authUpdated=!0,H.loginSucceeded)this.finish(H)}return}if(z!=="account/login/completed")return;if(!H.loginId){H.early.push(G);return}if(G?.loginId!==H.loginId)return;if(G?.success!==!0){this.finish(H,Error(typeof G?.error==="string"?G.error:"Codex 登录未成功"));return}if(H.loginSucceeded)return;if(H.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${H.authUpdated}`),H.timer)clearTimeout(H.timer);if(H.authUpdated)this.finish(H);else H.timer=setTimeout(()=>{this.finish(H,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},H.closed=(z)=>{this.finish(H,z)},Y.on("notification",H.notification),Y.on("closed",H.closed),Y.on("protocolError",H.closed),this.attempts.set($,H);try{await Y.initialize("lodestar-login"),H.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(H.loginId=z.loginId,H.finishing)throw await X,Error("登录已结束");H.timer=setTimeout(()=>{this.cancelAttempt(H,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let G of H.early)H.notification("account/login/completed",G);return H.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:X}}catch(z){return await this.finish(H,W4(z)),await X}}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};取消请求失败:${W4(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=W4(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,`登录进程关闭失败:${W4(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 W4($){return $ instanceof Error?$:Error(String($))}var o1;var nJ=O(()=>{A$();w0();f();o1=new FG});class K4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=DM){let Y=await J.sendCard($,P$(Z,!0));if(!Y)throw Error("Codex 账号卡片发送失败");let Q=await J.convertMessageToCard(Y);return J.recordCardCreated(Q,1),new K4(Q,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=y9($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=y9($);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,T.codexAccountPanel,Z,{notifyCardFailure:!1}),Q=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:k9($)}}});if(!Y||!Q)throw Error(`Codex 账号卡片更新失败:内容 ${Y?"OK":"MISS"},状态 ${Q?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var DM;var DG=O(()=>{r();f$();C0();J4();DM={sendCard:u,convertMessageToCard:L$,recordCardCreated:X$,replaceElementChecked:A0,patchSettingsChecked:R0,dispose:H$}});var oJ={};S$(oJ,{settleCodexAccountCards:()=>aJ,runCodexNamedHi:()=>UM,runCodexAccountCommand:()=>AM});import{createHash as MM}from"node:crypto";function u9($,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 MG($,Z){if(!await u($.chatId,P$(u9(Z))))throw Error("Codex 错误卡片发送失败")}async function UM($,Z){let J=await K4.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Y=k.find(Z),Q="";if(!await $.startWithCodexAccount(Y.id,{announce:!1,onStatus:(X)=>{Q=X}}))throw Error(Q||"指定账号启动失败");await J.finish({phase:"current",name:Y.name,current:Y.name,title:"已指定账号",hint:"本次手动指定 · 不参与自动排序"}),await $.showConsole()}catch(Y){await J.finish(u9(Y,Z))}}async function aJ(){let Z=(await Promise.allSettled([...s1.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function AM($,Z,J,Y,Q){if(Z==="reset"){await NM($,J,Q);return}let V={chatId:$.chatId,userOpenId:Y};if(Z==="login-cancel"){try{let G=o1.pending(V);if(!J&&G.length!==1)throw Error(G.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?k.find(J).id:G[0];await o1.cancel(W,V),await s1.get(W)}catch(G){await MG($,G)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,H=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),z=await K4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":H?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let L=k.find(J);if(s1.has(L.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:j}=k.remove(L.id);f2(L.id),await z.finish({phase:"deleted",name:L.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 L=J?Number(J):1;await N1();let j=$.codexAccountId(),q=V0("codex-sub",j),F=()=>$.currentProvider()==="codex"?$.currentModelLabel():q?.defaultModel,R=F(),D;if(!R)try{if(!q)throw Error("Codex 订阅来源尚未初始化");if(await q.refreshModels(),R=F(),!R)throw Error(q.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(S){D=`${k.get(j).name}:${S instanceof Error?S.message:String(S)}`}let U=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,A=R?await a3.choose({model:R,effort:U}):null,x=A?MJ(A.candidates.flatMap((S)=>S.usage?[{account:S.account,usage:S.usage,fingerprint:S.identity.startsWith("record:")?null:S.identity}]:[])):await s8();if(D)B(`codex-accounts: scheduling MISS: ${D}`);await z.finish({phase:"accounts",total:x,currentId:j,...k.preferred($.sessionName)?{selectedId:k.selected($.sessionName)}:{},page:L,...A?{scheduling:{candidates:A.candidates,ultra:U==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:D,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");k.selectAuto($.sessionName),await z.finish({phase:"selected",name:"自动选择",current:k.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await z.finish({phase:"current",current:k.get($.codexAccountId()).name,selected:k.preferred($.sessionName)===null?"自动 · 最高分优先":k.get(k.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let L=k.find(J),j=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,F=k.get($.codexAccountId()).name;if($.currentProvider()==="codex")z1($.sessionName,"codex",j,q,"codex-sub");if(k.select($.sessionName,L.id),$.currentProvider()==="codex")$.selectedModel=j,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await z.finish({phase:"selected",name:L.name,current:F,selected:L.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Y)throw Error("无法确认登录发起者");if(H)await qG(),await z.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let G=k.ensure(J);if(T3(G.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(s1.has(G.id))throw Error("登录结果正在更新,请稍等");let W=await o1.start(G.id,V);try{await z.update({phase:"waiting",flow:"login",name:G.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${G.name}`:""}`})}catch(L){throw await o1.cancel(G.id,V),L}let K=(async()=>{let L;try{L=await W.done}catch(q){await z.finish(u9(q,G.name));return}await z.update({phase:"checking",flow:"login",name:G.name,message:"授权完成,正在读取模型…"});let j;try{await N1();let q=V0("codex-sub",G.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 z.finish({phase:j?"warning":"success",flow:"login",name:G.name,email:L.email,plan:L.planType,...j?{title:"已登录 · 目录 MISS",details:j}:{},hint:`已加入自动选择 · 优先使用:codex-account ${G.id==="default"?"default":G.name}`})})();s1.set(G.id,K);let _=()=>{if(s1.get(G.id)===K)s1.delete(G.id)};K.then(_,(L)=>{B(`codex-login: terminal card write failed: ${L}`),_()})}catch(G){B(`codex-${Z}: ${G}`),await z.finish(u9(G,X))}}async function NM($,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(y0($.proc))}catch(G){B(`codex-reset: ${G}`),await MG($,G);return}let Q=await K4.open($.chatId,{phase:"checking",name:Y.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let G=MM("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await $X(Y.id,G)}catch(G){B(`codex-reset: ${G}`),await Q.finish(u9(G,Y.name));return}let X=OM[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(`
226
- `);await Q.finish({...X,name:Y.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var s1,OM;var B7=O(()=>{r();w0();nJ();Z0();UJ();O6();DG();J4();f();A$();s1=new Map;OM={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as RM}from"node:fs";import{homedir as TM}from"node:os";import{join as NG}from"node:path";function xM(){return process.env.CLAUDE_CONFIG_DIR||NG(TM(),".claude")}function sJ(){try{let $=RM(NG(xM(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function t1($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function SM($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function CM($){let Z=SM($);return Z&&t1($)?Z:null}function AG($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function OG($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function bM($){let Z=Array.isArray($)?$:Array.isArray($?.limits)?$.limits:void 0;if(!Z)return{state:"network",reason:"GLM 额度响应缺少 limits 数组"};let J=Z.filter((W)=>W?.type==="TOKENS_LIMIT"||W?.type==="CREDIT_LIMIT"),Y=J.find((W)=>W?.unit===3&&W?.number===5),Q=J.find((W)=>W?.unit===6&&W?.number===1),V=Z.find((W)=>W?.type==="TIME_LIMIT"),X=(W)=>W?{percent:AG(W.percentage),resetsAt:OG(W.nextResetTime)}:null,H=X(Y),z=X(Q),G=V?{percent:AG(V.percentage),resetsAt:OG(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!H&&!z&&!G)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:H,weekly:z,monthly:G,fetchedAt:Date.now()}}async function _7($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:sJ(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let V=CM(Q);if(!V)return{state:"not_glm",baseUrl:Q||void 0};return EM.read(w2("glm",V,Y),()=>kM(V,Y))}async function kM($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Y=new AbortController,Q=setTimeout(()=>Y.abort(),UG);try{let V=await z0(J,{headers:{Authorization:Z,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:Y.signal});if(!V.ok)return B(`glm-usage: quota/limit HTTP ${V.status}`),{state:V.status===429?"rate_limited":"network",reason:`HTTP ${V.status}`,retryAfterMs:R1(V.headers)};let X=await V.json(),H=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||H!==void 0&&String(H)!=="200"){let W=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[H===void 0?"":`code ${H}`,W===void 0?"":String(W)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(H)==="429"?"rate_limited":"network",reason:K,retryAfterMs:R1(V.headers)}}let z=X?.data??X,G=bM(z);if(G.state==="network")B(`glm-usage: quota/limit MISS: ${G.reason}`);return G}catch(V){let X=(V?.name==="AbortError"?`timeout ${UG}ms`:V?.message??String(V)).replaceAll(Z,"[redacted]");return B(`glm-usage: quota/limit fetch failed: ${X}`),{state:"network",reason:X}}finally{clearTimeout(Q)}}var UG=1e4,EM;var j7=O(()=>{o0();f();T1();EM=new W$});function wM($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function L7($,Z,J){try{let Y=await z0(wM($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(yM)});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 B(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return B(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var yM=15000;var tJ=O(()=>{o0();f()});function RG($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function vM($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function TG($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function fM($){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 hM($){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 rJ($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],..."retryAfterMs"in $?{retryAfterMs:$.retryAfterMs}:{},...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(RG($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(RG($.weekly,"weekly","周额度"));if($.monthly)Z.push(vM($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var eJ=O(()=>{Z0();j7();Q4();o4();tJ();f();x4();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)&&t1(J),V=$.model?.trim()||void 0,X=hM($.slots),H={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(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await Az(J,Y),W=[...new Set([...TG($.models),...TG($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:Y4,defaultEffort:"max",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=fM(H.models.map((K)=>K.model));for(let K of H.models){let _=E2("glm",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`glm refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...r0(z)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_AUTH_TOKEN=Y,X.opus)W.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)W.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)W.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return W},resolveSpawnModel(z){return w3("glm",z)},async verifyModel(z){return L7(J,{Authorization:`Bearer ${Y}`},z)},async readUsage(){return rJ(await _7(J,Y))}};return H},setup:{commandSuffix:"glm",hint:($)=>`配置 ${$}:发送 \`glm-setup <api_key>\`(智谱国内站),或 \`glm-setup <base_url> <api_key>\`(指定平台)。Claude Code 和 DeepSeek Harness 共用该账号;校验失败保留原配置。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:glm-setup <api_key>,或 glm-setup <base_url> <api_key>;只填写 Key 本身,不加 Bearer 前缀。"};try{return{config:{agent:"claude",base_url:E4(Z.length===2?Z[0]:B2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await _2($.base_url??B2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!t1(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var EG=O(()=>{Z0();Q4();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 t8(),!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 IM(){let $=Object.fromEntries(p3.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function gM($){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 xG=O(()=>{j0();f();Z0();Q4();SJ();d1();M0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=IM(),J=$.model?.trim(),Y="Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用",Q,V={id:"claude-sub",kind:"claude-subscription",agent:"claude",display:$.display?.trim()||"Claude Code 订阅",enabled:$.enabled!==!1,models:[],defaultModel:J??"",modelCatalogState:$.enabled===!1?{status:"disabled",updatedAt:Date.now(),error:"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"}:{status:"idle",updatedAt:Date.now()},settingSources:["user","project","local"],claudeSettings:Z,validateClaudeAccount:gM,spawnEnv(X){return{...r0(X),...Z.env}},resolveSpawnModel(X){return X},async refreshModels(){if($.enabled===!1){V.enabled=!1,V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now(),error:"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"};return}V.enabled=!0,V.models=[],V.modelCatalogState={status:"loading",updatedAt:null};try{let X=await t8({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id});if(!X.length)throw Error("Claude Code 订阅模型目录为空");let H=[...q0($.custom_models),...q0($.models)];if(J&&!X.some((z)=>z.model===J)&&!H.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let z=X.find((G)=>G.model===(J??X[0].model));if(!F0($.effort)||z&&!z.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(z)z.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let H=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${H}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:H}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Q??=kz({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Q=void 0}),Q}};return V}})});function CG($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function mM($){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 pM($){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 cM($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function bG($,Z){return(await $Y(new URL($).origin,Z)).map((Y)=>({model:Y,display:Y,efforts:Y4,defaultEffort:"high"}))}async function $Y($,Z){let J=new URL($);if(!["https:","http:"].includes(J.protocol)||J.username||J.password||J.search||J.hash)throw Error("DeepSeek 需要无凭据和查询参数的 HTTP(S) API 根地址");return(await l$(`${J.toString().replace(/\/+$/,"")}/models`,Z,"DeepSeek models")).map((Q)=>{if(typeof Q.id!=="string"||!Q.id.trim())throw Error("DeepSeek models 模型 id 无效");return Q.id})}async function ZY($,Z){if(!Z.trim())return{kind:"balance",state:"no_credentials",windows:[]};let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}return lM.read(w2("deepseek",J,Z),()=>dM(J,Z))}async function dM($,Z){try{let J=await z0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(uM)});if(!J.ok)return B(`deepseek readUsage MISS: HTTP ${J.status}`),{kind:"balance",state:J.status===429?"rate_limited":"network",windows:[],reason:`HTTP ${J.status}`,retryAfterMs:R1(J.headers)};let Y=await J.json(),V=(Array.isArray(Y?.balance_infos)?Y.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",H=V?.total_balance;if(!X||typeof H!=="string"&&typeof H!=="number"||String(H).trim()===""||!Number.isFinite(Number(H)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(H),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var SG="https://api.deepseek.com/anthropic",uM=1e4,lM;var JY=O(()=>{o0();Z0();Q4();o4();tJ();f();T4();T1();lM=new W$;M0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||SG,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,V=$.model?.trim()||void 0,X=pM($.slots),H={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(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await bG(J,Y),W=[...new Set([...CG($.models),...CG($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:Y4,defaultEffort:"high",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=mM(H.models.map((K)=>K.model));for(let K of H.models){let _=E2("deepseek",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`deepseek refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...r0(z)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_API_KEY=Y,X.opus)W.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)W.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)W.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return W},resolveSpawnModel(z){return w3("deepseek",z)},async verifyModel(z){return L7(J,{"x-api-key":Y},z)},async readUsage(){if(!Y)return{kind:"balance",state:"no_credentials",windows:[]};return ZY(J,Y)}};return H},setup:{commandSuffix:"deepseek",hint:($)=>`配置 ${$}:发送 \`deepseek-setup <api_key>\`;Claude Code 和 DeepSeek Harness 共用该账号。自建端点用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))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}}},async validate($){await bG($.base_url??SG,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!cM(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function r1($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var YY;var kG=O(()=>{YY=[{rank:1,lab:"Anthropic",model:"anthropic/claude-fable-5.1",effort:"max"},{lab:"Anthropic",model:"anthropic/claude-opus-5",effort:"max"},{rank:3,lab:"Moonshot",model:"moonshotai/kimi-k3",effort:"max"},{rank:4,lab:"Tencent",model:"tencent/hy4-preview",effort:"high"},{rank:7,lab:"Google",model:"google/gemini-3.8-flash",effort:"high"},{rank:8,lab:"SpaceXAI",model:"x-ai/grok-4.5",effort:"high"},{rank:9,lab:"Alibaba",model:"qwen/qwen3.8-max-0902",effort:"xhigh"},{rank:10,lab:"Meta",model:"meta/muse-spark-1.2",effort:"xhigh"},{rank:11,lab:"Xiaomi",model:"xiaomi/mimo-v2.5-pro",effort:"default"},{rank:12,lab:"MiniMax",model:"minimax/minimax-m3",effort:"default"},{lab:"ByteDance",model:"bytedance-seed/seed-2-1-turbo",effort:"default"},{lab:"Meituan",model:"meituan/longcat-2.0",effort:"default"}]});function e1($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function VY($){return $ instanceof Error?$.message:String($)}function wG($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function B4($){return $.replace(/\[1m\]$/,"")}function _4($){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 aM($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Y=await z0(`${_4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(iM)});if(!Y.ok){let Q=await Y.text(),V="";if(Q.trim().startsWith("{"))try{let X=JSON.parse(Q);if(e1(X)&&e1(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new P7(Y.status,V.replaceAll(Z,"[redacted]"),R1(Y.headers))}return Y.json()}async function vG($,Z){let J=await l$(`${_4($)}/v1/models/user`,Z,"OpenRouter models"),Y=[],Q=new Set;for(let V of J){if(!e1(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!e1(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(r1(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Q.has(V.id))continue;let X=e1(V.reasoning)?V.reasoning:void 0,H=X?.supported_efforts,z=H===null||H===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(H)?[...new Set(H.filter((_)=>_!=="default"&&F0(_)))]:["default"],G=YY.find((_)=>_.model===V.id),W=G?z.includes(G.effort)?G.effort:null:z[0]==="default"?"default":F0(X?.default_effort)&&z.includes(X.default_effort)?X.default_effort:null,K=E2("openrouter",V.id);Y.push({model:V.id,display:V.name,efforts:z,defaultEffort:W,context1m:K!==void 0&&K>=1e6||void 0}),Q.add(V.id)}if(!Y.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Y}function fG($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function oM($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return nM.read(w2("openrouter",_4($),Z),()=>sM($,Z))}async function sM($,Z){try{let J=await aM($,Z,"credits");if(!e1(J)||!e1(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Y,total_usage:Q}=J.data;if(!fG(Y)||!fG(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=VY(J);return B(`openrouter readUsage MISS: ${Y}`),{kind:"balance",state:J instanceof P7&&J.status===429?"rate_limited":"network",windows:[],reason:Y,...J instanceof P7?{retryAfterMs:J.retryAfterMs}:{}}}}var yG="https://openrouter.ai/api",iM=1e4,nM,QY,P7;var hG=O(()=>{o0();j0();Z0();o4();f();kG();T4();T1();nM=new W$,QY={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};P7=class P7 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};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()||yG,V=$.model?.trim()||"",X=$.models===void 0?YY.map((z)=>z.model):wG($.models),H={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Y,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(z){if(r1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let G=H.modelSelection.availableModels.find((W)=>B4(W.model)===B4(z));if(!G||G.unavailableReason||!G.efforts.length)return"model-unavailable";return G.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(H.models=[],H.modelSelection.availableModels=[],!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await vG(Q,Y),G=z.find((K)=>K.model===B4(V));if(V&&!G)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!F0($.effort)||!G.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);G.defaultEffort=$.effort}let W=X.map((K)=>{let _=z.find((L)=>L.model===B4(K));if(!_)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:r1(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:K}});H.models=W,H.modelSelection.availableModels=z,H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let G=VY(z);B(`openrouter refreshModels MISS: ${G}`),H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G}}},spawnEnv(z,G){if(!Y)throw Error("OpenRouter API key missing");let W=G||V;if(!W)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(r1(W))throw Error(`OpenRouter 已排除此厂商或自动路由: ${W}`);let K=r0(z);K.ANTHROPIC_BASE_URL=_4(Q),K.ANTHROPIC_AUTH_TOKEN=Y,K.ANTHROPIC_API_KEY="",K.CLAUDE_CODE_NO_MODEL_FALLBACK="1",K.ANTHROPIC_MODEL=W,K.ANTHROPIC_SMALL_FAST_MODEL=W,K.CLAUDE_CODE_SUBAGENT_MODEL=W,K.ANTHROPIC_DEFAULT_FABLE_MODEL=W;for(let _ of Object.values(QY))K[_]=W;for(let _ of wG($.slots)){let L=_.indexOf("="),j=_.slice(0,L).trim(),q=_.slice(L+1).trim();if(L<1||!Object.hasOwn(QY,j)||!q)throw Error(`OpenRouter slots 无效: ${_}`);if(r1(q)||!H.modelSelection.availableModels.some((F)=>!F.unavailableReason&&B4(F.model)===B4(q)))throw Error(`OpenRouter slot 模型不在账号目录中: ${q}`);if(H.modelEnvironmentRevision(q)!==H.modelEnvironmentRevision(W))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${q}`);K[QY[j]]=q}return K},resolveSpawnModel(z){if(r1(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return oM(Q,Y)}};return H},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:_4(Z[0])}:{}}}}catch(J){return{error:VY(J)}}},async validate($){await vG($.base_url??yG,$.api_key??$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Y=_4(Z);if(new URL(Y).hostname!=="openrouter.ai")return null;return{base_url:Y,api_key:J}}catch{return null}}}})});var IG=O(()=>{Z0();j0();f4();Q0();JY();d1();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=s4(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:G2,env:Y.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...q0($.models),...q0($.custom_models)]});if(!Array.isArray(Q)||!Q.length)throw Error("DeepSeek Harness model catalog is empty");for(let X of Q)if(!X.model||!X.efforts.length||!X.efforts.every(_0)||!_0(X.defaultEffort)||!X.efforts.includes(X.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${X.model}`);let V=$.model?.trim()||Q.find((X)=>X.isDefault)?.model;if(!V||!Q.some((X)=>X.model===V))throw Error("DSH default model is not in its catalog");Y.models=Q.map(({model:X,display:H,efforts:z,defaultEffort:G,isCustom:W})=>{let K=$.effort?.trim();if(K&&(!_0(K)||!z.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:H,efforts:z,defaultEffort:K?K:G,origin:W?"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 b2(Y).find((V)=>V.model===Q)?.model},readUsage(){return Z?ZY(J,Z):Promise.resolve({kind:"balance",state:"no_credentials",windows:[]})}};return Y},setup:{commandSuffix:"deepseek-harness",hint:()=>"DeepSeek 账号由 Claude Code 和 DeepSeek Harness 共用。发送 `deepseek-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||/^https?:\/\//i.test(Z.at(-1)))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]}:{}}}},async validate($){await $Y($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function q7($){let Z=new URL($);if(!t1(Z.origin)||Z.protocol!=="https:"||Z.username||Z.password||Z.search||Z.hash)throw Error("DSH GLM 需要智谱或 Z.ai 的 Coding Plan HTTPS 端点;地址中不能包含凭据或查询参数");return Z.pathname="/api/coding/paas/v4",Z.search="",Z.hash="",Z.toString().replace(/\/$/,"")}async function gG($,Z){return(await l$(`${$}/models`,Z,"GLM Coding Plan models")).map((Y)=>{if(typeof Y?.id!=="string"||!Y.id)throw Error("GLM Coding Plan 模型 id 无效");return{model:Y.id,display:typeof Y.name==="string"?Y.name:Y.id}})}var mG=O(()=>{T4();S0();j0();Z0();f4();Q0();j7();eJ();d1();M0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=v.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Y=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Y&&t1(Y)?{api_key:J,base_url:q7(Y)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Y=q7($.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,X={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(H){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=s4(H);if(z.LODESTAR_DSH_PROVIDER=Q,z.LODESTAR_DSH_GLM_API_KEY=J,z.LODESTAR_DSH_BASE_URL=Y,z.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel,V)z.LODESTAR_DSH_MODELS=JSON.stringify(V);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(X.models=[],V=void 0,!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let H=await gG(Y,J),z=[...H];for(let W of[...q0($.models),...q0($.custom_models)])if(!z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))z.push({model:W,display:W});if(V=z.map((W)=>W.model),!$.model?.trim()){let W=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...H].sort((K,_)=>W(_.model)-W(K.model))[0].model}let G=await q2({cwd:G2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=z.map((W)=>{let K=G.find((q)=>q.model===W.model),_=AJ(X,$),L=K?K.efforts.filter(_0):_.efforts,j=$.effort?.trim()||K?.defaultEffort||_.defaultEffort;return{...W,display:K?.display??W.display,efforts:L,defaultEffort:_0(j)&&L.includes(j)?j:null,origin:H.some((q)=>q.model===W.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H instanceof Error?H.message:String(H)},H}},resolveSpawnModel(H){return b2(X).find((z)=>z.model===H&&!z.unavailableReason)?.model},async readUsage(){return J?rJ(await _7(Y,J)):{state:"no_credentials",windows:[]}}};return X},setup:{commandSuffix:"dsh-glm",hint:()=>"GLM Coding Plan 账号由 Claude Code 和 DeepSeek Harness 共用。发送 `glm-setup <api_key>` 配置两边;`dsh-glm-setup [base_url] <api_key>` 同样更新共享账号。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:dsh-glm-setup [base_url] <api_key>"};try{return{config:{agent:"dsh",api_key:Z.at(-1),base_url:q7(Z.length===2?Z[0]:"https://open.bigmodel.cn/api/coding/paas/v4")}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await gG(q7($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var cG={};S$(cG,{tokenSourceSpawnRevision:()=>pG,buildTokenSourcesFromConfig:()=>XY});import{createHash as tM}from"node:crypto";function XY(){let $=sJ(),Z=Object.fromEntries(O1().flatMap((H)=>{let z=H.detect?.fromSettingsEnv($);return H.configSectionId&&z?[[H.configSectionId,z]]:[]})),J=J7(v.token_sources??{},Z),Y=O1().map((H)=>{let z=H.configSectionId?J[H.configSectionId]??{}:{},G=H.configSectionId?Z[H.configSectionId]??null:null,W=r8(H.build(z,G),z);return W.spawnRevision=pG(H.kind,z,G),W}),Q=Y.find((H)=>H.kind==="claude-native");if(Q){let H=Y.some((z)=>z.agent==="claude"&&z.enabled&&z.kind!=="claude-native"&&z.kind!=="claude-subscription");Q.enabled=!H,Q.modelCatalogState={status:Q.enabled?"idle":"disabled",updatedAt:Date.now()}}q6();for(let H of Y)j6(H);let X=Y.find((H)=>H.enabled&&v.token_sources?.[H.id]?.default===!0)??Y.find((H)=>H.enabled);if(X)P6(X.id);return Y.length}function pG($,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 tM("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var HY=O(()=>{S0();Z0();j7();d1();v9();NJ();eJ();EG();xG();JY();hG();IG();mG()});import{readFileSync as rM}from"node:fs";function eM($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function $U($,Z){let J=[`[token_source.${$}]`],Y=(Q,V)=>{if(V!==void 0)J.push(`${Q} = "${eM(V)}"`)};if(Y("agent",Z.agent),Z.enabled!==void 0)J.push(`enabled = ${Z.enabled}`);if(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(`
227
- `)}function ZU($,Z){let J=rM(E0,"utf8"),Y=TJ(h4().token_sources,$,Z),Q=new Set(Object.keys(Y).map((z)=>`[token_source.${z}]`)),V=J.split(`
228
- `),X=!1,H=[];for(let z of V){let G=z.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(G)X=Q.has(G);if(!X)H.push(z)}while(H.length&&H[H.length-1]==="")H.pop();g0(E0,H.join(`
224
+ `),V=Q[Q.length-1];B(`session "${$.sessionName}": multi-msg flush ${Q.length} segment(s) → 1 turn`),await $.onUserMessage(Y,[],V.userOpenId,V.msgId)}function uJ($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;B(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Q,Y]of $.multiMsgReactions){if(Y)k0(Q,Y);t0(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var ez=O(()=>{r();h();tz()});import{mkdtemp as QU,rm as YU,writeFile as VU}from"node:fs/promises";import{createRequire as XU}from"node:module";import{tmpdir as HU}from"node:os";import{join as $W}from"node:path";function LU($){let Z=YW.get($);if(Z)return Z;let{liteAdaptor:J}=$2("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Q}=$2("mathjax-full/js/handlers/html.js"),{mathjax:Y}=$2("mathjax-full/js/mathjax.js"),{TeX:V}=$2("mathjax-full/js/input/tex.js"),{AllPackages:X}=$2("mathjax-full/js/input/tex/AllPackages.js"),{SVG:H}=$2("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Q(z);let W=Y.document("",{InputJax:new V({packages:X}),OutputJax:new H({fontCache:"none"})}),G={adaptor:z,doc:W};return YW.set($,G),G}function VW($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function qU($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function FU($,Z=iJ,J=!0){try{let Q=Z*zU,{adaptor:Y,doc:V}=LU(Z),X=V.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),H=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(H)){let L0=H.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(L0)}let z=H.indexOf("<svg"),W=H.lastIndexOf("</svg>");if(z<0||W<0)throw Error("MathJax returned no SVG");let G=H.slice(z,W+6),K=G.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let _=VW(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),L=VW(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),j=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!j)throw Error("MathJax SVG missing viewBox");let q=j.trim().split(/[\s,]+/).map(Number);if(q.length!==4||q.some((L0)=>!Number.isFinite(L0))||q[2]<=0||q[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[P,N,D,U]=q,M=/<text\b/.test(G)?_U:0,T=`${P} ${N} ${D+M} ${U}`,x=_*Q,w=M*(x/D),b=Math.max(1,Math.ceil(x+w)),v=Math.max(1,Math.ceil(L*Q)),C=WU-lJ*2,f=Math.min(1,C/b),m=Math.max(1,Math.round(b*f)),l=Math.max(1,Math.round(v*f));if(f<1&&l<GU)throw Error(`formula would be unreadable after width cap (${m}x${l})`);let A=m+lJ*2,k=l+JW*2,d=G.slice(K.length,-6).replace(/currentColor/g,ZW).replace(/font-family="serif"/g,`font-family="${jU}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${A}" height="${k}" viewBox="0 0 ${A} ${k}" style="color:${ZW}">`,`<rect x="0" y="0" width="${A}" height="${k}" rx="6" fill="${WW}"/>`,`<svg x="${lJ}" y="${JW}" width="${m}" height="${l}" viewBox="${qU(T)}" preserveAspectRatio="xMidYMid meet">`,d,"</svg>","</svg>"].join(""),width:A,height:k}}catch(Q){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function PU($,Z=iJ,J=!0){let Q=FU($,Z,J);if(!Q)return null;try{let{Resvg:Y}=$2("@resvg/resvg-js"),X=new Y(Q.svg,{background:WW,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:QW,sansSerifFamily:QW}}).render().asPng(),H=new DataView(X.buffer,X.byteOffset,X.byteLength),z=H.getUint32(16),W=H.getUint32(20);if(z!==Q.width||W!==Q.height)throw Error(`PNG dimensions ${z}x${W} != SVG ${Q.width}x${Q.height}`);return{png:X,width:z,height:W}}catch(Y){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function DU($){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 XW($,Z){let J=[],Q=(G,K,_)=>{let L=G[0],j=K.trim();if(!j)return;J.push({start:Z+G.index,end:Z+G.index+L.length,tex:j,raw:L,display:_})},Y,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Y=V.exec($))!==null)Q(Y,Y[1]??Y[2]??"",!0);let X=/\\\(([\s\S]+?)\\\)/g;while((Y=X.exec($))!==null)Q(Y,Y[1]??"",!1);let H=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=H.exec($))!==null){let G=(Y[1]??"").trim();if(DU(G))Q(Y,G,!1)}J.sort((G,K)=>G.start-K.start||K.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 GW($){let Z=s7($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...XW($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...XW($.slice(Q),Q));return J}function UU($){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,Q)=>{if(HW[Q])return HW[Q];if(Q==="times")return"×";if(Q==="cdot")return"·";if(Q==="div")return"÷";if(Q==="pm")return"±";if(Q==="leq"||Q==="le")return"≤";if(Q==="geq"||Q==="ge")return"≥";if(Q==="neq"||Q==="ne")return"≠";if(Q==="approx")return"≈";if(Q==="sim")return"~";if(Q==="infty")return"∞";if(Q==="partial")return"∂";if(Q==="nabla")return"∇";if(Q==="sqrt")return"√";if(Q==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Q,Y)=>Y.length===1?`${Q}${Y}`:`${Q}(${Y})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function NU($){let Z=zW.get($);if(Z!==void 0)return Z;return Z=AU++,zW.set($,Z),Z}function RU($,Z){return`${BU}\x00${NU(Z)}\x00${$}`}function TU($){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 EU($,Z){let J=RU($,Z),Q=e1.get(J);if(Q)return Q;let Y=dJ.get(J);if(Y)return Y;let V=(async()=>{let X=PU($,iJ,!0);if(!X)return null;let H=null;try{H=await QU($W(HU(),"lodestar-math-"));let z=$W(H,`formula-${TU($)}.png`);await VU(z,X.png);let W=await Z(z,{tex:$,width:X.width,height:X.height});if(!W)return B(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:W,width:X.width,height:X.height};if(e1.has(J))e1.delete(J);e1.set(J,G);while(e1.size>OU){let K=e1.keys().next().value;if(typeof K!=="string")break;e1.delete(K)}return G}catch(z){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(H)try{await YU(H,{recursive:!0,force:!0})}catch(z){B(`math-render: temp cleanup failed for ${H}: ${z}`)}}})();dJ.set(J,V);try{return await V}finally{dJ.delete(J)}}function xU($,Z,J){let Q=$.width<=KU;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:Q?"crop_center":"fit_horizontal",...Q?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function KW($,Z={}){let J=GW($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??MU,Y=await Promise.all(J.map(async(G)=>{if(!G.display){let K=UU(G.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await EU(G.tex,Q)}})),V=[],X="",H=0,z=0,W=()=>{if(!X)return;if(X.trim())V.push({type:"markdown",text:X});X=""};for(let G=0;G<J.length;G++){let K=J[G],_=Y[G];if(X+=$.slice(H,K.start),_.unicode!==null){X+=_.unicode,H=K.end;continue}let L=_.uploaded;if(!L){X+=K.raw,H=K.end;continue}W(),V.push(xU(L,K,z++)),H=K.end}if(X+=$.slice(H),W(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function nJ($){return GW($).length>0}var $2,zU=0.5,iJ=22,ZW="#1F2329",WW="#F7F8FA",lJ=12,JW=8,WU=720,GU=14,KU=278,BU="v4-native-cjk-tail-pad",_U=1100,QW,jU="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",YW,HW,MU=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (r(),J0));return Z($)},zW,AU=1,e1,dJ,OU=512;var BW=O(()=>{h();$2=XU(import.meta.url),QW=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",YW=new Map;HW={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:"Ω"};zW=new WeakMap,e1=new Map,dJ=new Map});import{readFileSync as CU}from"node:fs";function B4($){return aJ.has($)}function n9($){aJ.add($)}function a9($){aJ.delete($)}function _4(){try{let $={};for(let[Z,J]of e0)$[Z]=J;o(F5,$)}catch($){throw B(`notify-callbacks: save failed (${F5}): ${$}`),$}}function qW(){let $=[],Z;try{Z=CU(F5,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Q=Date.now()-LW,Y=0,V=0;for(let X of Object.values(J)){if(!X||typeof X!=="object")continue;if(typeof X.notifyId!=="string"||typeof X.callbackUrl!=="string")continue;if(typeof X.createdAt!=="number"||X.createdAt<Q){Y++;continue}if(X.replyState?.status==="sending"&&!X.resolvedAt&&!X.unknownAt)X.unknownAt=Date.now(),X.unknownBy={openId:X.replyState.openId},X.unknownReason="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",V++;if(e0.set(X.notifyId,X),X.replyState?.status==="sending"&&X.unknownAt)$.push(X)}if(B(`notify-callbacks: loaded ${e0.size} registration(s)${Y?`, dropped ${Y} stale`:""}`),V)B(`notify-callbacks: ${V} interrupted text reply(s) marked UNKNOWN`);if(Y>0||V>0)_4()}catch(J){B(`notify-callbacks: load failed (${F5}): ${J}`)}return $}function FW($){let Z=Date.now();if(Z-jW>=bU)kU(Z),jW=Z;e0.set($.notifyId,$),_4()}function d$($){return e0.get($)}function oJ($){return[...e0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function o9($,Z){if(!$)return;return oJ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function PW($,Z){return!!Z&&[...e0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function j4($,Z){let J=e0.get($);if(!J)throw Error(`notify registration not found: ${$}`);let{replyState:Q,replyMessageIds:Y}=J;if(J.replyState=Z,Z.response&&!J.replyMessageIds?.includes(Z.response.message_id))J.replyMessageIds=[...J.replyMessageIds??[],Z.response.message_id];try{_4()}catch(V){if(Q)J.replyState=Q;else delete J.replyState;if(Y)J.replyMessageIds=Y;else delete J.replyMessageIds;throw V}}function s9($,Z,J){let Q=e0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);let Y={resolvedAt:Q.resolvedAt,resolvedBy:Q.resolvedBy,unknownAt:Q.unknownAt,unknownBy:Q.unknownBy,unknownReason:Q.unknownReason};Q.resolvedAt=Date.now(),Q.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Q.unknownAt,delete Q.unknownBy,delete Q.unknownReason;try{_4()}catch(V){if(Y.resolvedAt===void 0)delete Q.resolvedAt;else Q.resolvedAt=Y.resolvedAt;if(Y.resolvedBy===void 0)delete Q.resolvedBy;else Q.resolvedBy=Y.resolvedBy;if(Y.unknownAt===void 0)delete Q.unknownAt;else Q.unknownAt=Y.unknownAt;if(Y.unknownBy===void 0)delete Q.unknownBy;else Q.unknownBy=Y.unknownBy;if(Y.unknownReason===void 0)delete Q.unknownReason;else Q.unknownReason=Y.unknownReason;throw V}}function sJ($,Z,J,Q){let Y=e0.get($);if(!Y)throw Error(`notify registration not found: ${$}`);delete Y.resolvedAt,delete Y.resolvedBy,Y.unknownAt=Date.now(),Y.unknownBy={...Z!==void 0?{buttonId:Z}:{},openId:J},Y.unknownReason=Q,_4()}function P5($,Z,J){try{return s9($,Z,J),{state:"complete"}}catch(Q){let V=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{sJ($,Z,J,V)}catch(X){let H=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${H}`;let z=e0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function kU($=Date.now()){let Z=$-LW,J=0;for(let[Q,Y]of e0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)e0.delete(Q),J++;if(J>0)_4();return J}async function tJ($,Z,J){let Q={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)},Y=new AbortController,V=setTimeout(()=>Y.abort(),_W);try{let X=await SY($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let z;try{let W=(await X.text()).trim();if(W.startsWith("{")){let G=JSON.parse(W),K=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(K.trim())z=K.trim().slice(0,500)}else if(W)z=W.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:z}}let H="";try{H=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${H?` ${H}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${_W}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function DW($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((H)=>H.id===Q):void 0,V=$.replyState?.response,X=Q!==void 0?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q}}:V?{response:{type:"text",...V}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Q===void 0?"resolved":J&&Q===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?{...X,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...X,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var LW=604800000,_W=2500,e0,jW,bU=86400000,aJ,F5;var t9=O(()=>{u0();h();V0();x0();e0=new Map,jW=Date.now(),aJ=new Set;F5=qY});function D5($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function L4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(o9($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(D5($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function rJ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Q=J.currentIdx===void 0?void 0:o9($.chatId)?"notification":D5($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Q}}function eJ($,Z){let J=$.pendingAsks.get(Z),Q=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||L4($,Z)||!Q?.userOpenId||!Q.messageId)return;J.announced=!0;let Y=(J.announcementVersion??0)+1;J.announcementVersion=Y;let V=J.questions[J.currentIdx]?.question.trim()??"",X=V.length>40?V.slice(0,40)+"…":V,H=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(g0(Q.cardId),await J5(Q.cardId,{config:{summary:{content:H}}}),$.currentTurn!==Q||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Y||J.currentIdx===void 0||L4($,Z))return;await n1(Q.messageId,[Q.userOpenId])})().catch((z)=>B(`session "${$.sessionName}": question notification failed: ${z}`))}function U5($){let Z=$.currentTurn;if(!Z)return;for(let[J,Q]of $.pendingAsks){let Y=Z.toolByUseId.get(J);if(!Y||Q.currentIdx===void 0)continue;let V=rJ($,J);if(V.waitingFor)Q.announced=!1,Q.announcementVersion=(Q.announcementVersion??0)+1;Y0(Z.cardId,E.tool(Y.i),u2(Y.i,J,Q.questions,"\uD83E\uDD14",V)),eJ($,J)}}function UW($){return D5($)!==void 0}async function MW($,Z,J,Q){let Y=D5($);if(!Y){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Q);return}let[V,X]=Y,H=L4($,V);if(H){let W=`${H}。这条文字未提交,请稍后重新发送。`;if(!await S($.chatId,W))throw Error(`提问等待提示发送失败: ${W}`);return}if(await $Q($,V,X.currentIdx,Z,J)&&Q)t0(Q,"CheckMark")}async function AW($,Z,J,Q,Y){let V=$.pendingAsks.get(Z);if(!V)return B(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==V.currentIdx)return B(`session "${$.sessionName}": stale ask click q=${J} current=${V.currentIdx}`),!1;return OW($,Z,{optionIdx:Q,user:Y})}async function $Q($,Z,J,Q,Y){let V=$.pendingAsks.get(Z);if(!V)return B(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let X=(Q??"").trim();if(!X)return B(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==V.currentIdx)return B(`session "${$.sessionName}": stale ask custom q=${J} current=${V.currentIdx}`),!1;return OW($,Z,{customText:X,user:Y})}function OW($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=L4($,Z);if(Y)return B(`session "${$.sessionName}": ask ${Z} waiting: ${Y}`),!1;let V=Q.currentIdx,X=Q.questions[V];if(!X)return B(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let H;if(J.customText!==void 0)H=J.customText;else if(J.optionIdx!==void 0){let _=X.options?.[J.optionIdx];if(!_)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;H=_.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[X.question]=H,Q.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Q.questions.length,W=void 0;for(let _=V+1;_<z;_++)if(!Q.answered.has(_)){W=_;break}Q.currentIdx=W;let G=$.currentTurn,K=G?.toolByUseId.get(Z);if(G&&K){let _=u2(K.i,Z,Q.questions,W===void 0?"✅":"\uD83E\uDD14",{currentIdx:W,answered:Q.answered});Y0(G.cardId,E.tool(K.i),_)}if(W===void 0)if(Q.requestId)ZQ($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),U5($);return!0}function ZQ($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Q=$.currentTurn?.toolByUseId.get(Z),Y=Q?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Y,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Q)Q.output=JSON.stringify({answers:J.answers}),Q.isError=!1;if($.pendingAsks.delete(Z),U5($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var M5=O(()=>{u$();H$();r();h();t9()});import{isAbsolute as yU}from"node:path";function T0($){if($?.planLiveInserted)return E.planLive;return $?.taskLiveInserted?E.taskBoardLive:E.footer}function vU($){return $==="ImageGeneration"||$==="imageGeneration"}function fU($,Z,J){if(J||!vU($))return null;let Q=q5(Z.trim());return yU(Q)?Q:null}function hU($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function NW($,Z,J){return $==="read"?L9(Z,J):j9(Z,J)}function RW($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=hU(J);if(Y&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,W=$.currentTurn.toolBatches.get(z);if(W&&W.kind===Y){let G=W.items.length;W.items.push({toolUseId:Z,input:Q,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:z,name:J,input:Q,batchSlot:G});let K=Y==="read"?L9(z,W.items):j9(z,W.items);Y0($.currentTurn.cardId,E.tool(z),K),A5($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let V=p1(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,M0(z.cardId,c1($.taskBoard),{type:"insert_before",targetElementId:E.footer});else Y0(z.cardId,E.taskBoardLive,c1($.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 K=W?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:K,name:J,input:Q});let _=j1(K,$.taskBoard,{name:V,status:"⏳"});G?M0(z.cardId,_,{type:"insert_before",targetElementId:T0(z)}):Y0(z.cardId,E.tool(K),_),A5(z,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let z=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:z}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let W=Y==="read"?L9(X,z):j9(X,z);M0($.currentTurn.cardId,W,{type:"insert_before",targetElementId:T0($.currentTurn)}),A5($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let z=Array.isArray(Q?.questions)?Q.questions:[],W=z.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:z,i:X,answers:{},answered:G,currentIdx:W});let K=u2(X,Z,z,"\uD83E\uDD14",rJ($,Z));M0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:T0($.currentTurn)}),eJ($,Z);return}let H=E$(X,J,Q,null,"⏳");M0($.currentTurn.cardId,H,{type:"insert_before",targetElementId:T0($.currentTurn)}),A5($.currentTurn,J,Q)}function A5($,Z,J){if(!$)return;let Q=z1(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,V=f1(Z),X=Y?`\uD83D\uDD27 ${V}: ${Y}`:`\uD83D\uDD27 ${V}`;X4($.cardId,X)}function TW($,Z,J,Q,Y){if(!$.currentTurn)return;let V=$.currentTurn.toolByUseId.get(Z);if(!V)return;if(Y&&typeof Y==="object")V.input={...V.input,...Object.fromEntries(Object.entries(Y).filter(([,G])=>G!==void 0))};let X=typeof J==="string"?J:Array.isArray(J)?J.map((G)=>G?.text??JSON.stringify(G)).join(`
225
+ `):JSON.stringify(J);if(V.output=X,V.isError=Q,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=fU(V.name,X,Q);if(H){IU($,$.currentTurn,V,H),Z2($);return}if(V.name==="AskUserQuestion"){Z2($);return}if(V.batchSlot!=null){let G=$.currentTurn.toolBatches.get(V.i);if(G){let K=G.items[V.batchSlot];if(K)K.output=X,K.isError=Q;let _=NW(G.kind,V.i,G.items);Y0($.currentTurn.cardId,E.tool(V.i),_)}Z2($);return}let z=p1(V.name);if(z){gU($,V,z,V.input,X,Q,V.resolvedNote);return}let W=E$(V.i,V.name,V.input,X,Q?"❌":"✅",V.resolvedNote);Y0($.currentTurn.cardId,E.tool(V.i),W),Z2($)}function IU($,Z,J,Q){if(Z.outboundSeenPaths.has(Q))return;Z.outboundSeenPaths.add(Q);let Y=Z.cardId,V=E.tool(J.i),X=Z.imageDeliveryInflight??=new Map,H=X.get(Y)??new Set;X.set(Y,H);let z=(async()=>{let W=null;try{W=await MJ(Q)}catch(K){B(`generated image upload failed: ${K}`)}if(W){let K=!1;try{K=await A0(Y,V,E$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1})}catch(_){B(`generated image embed failed: ${_}`)}if(K){J.imageKey=W,Z.outboundSentPaths.add(Q);return}B(`generated image could not be embedded in card ${Y}; sending it as a separate message`)}let G=W?await $5($.chatId,W)!==null:await w9($.chatId,Q);if(G)Z.outboundSentPaths.add(Q);else B(`generated image delivery failed: ${Q}`);if(J.resolvedNote=G?"图片已单独发送。":"图片发送失败。",await A0(Y,V,E$(J.i,J.name,J.input,J.output??null,G?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1}),!G&&W)await S($.chatId,"❌ 生成图片发送失败,请稍后重试。")})().catch(async(W)=>{B(`generated image delivery failed: ${W}`),await S($.chatId,`❌ 生成图片发送失败:${W instanceof Error?W.message:String(W)}`)});H.add(z),z.finally(()=>{if(H.delete(z),!H.size)X.delete(Y)}).catch((W)=>B(`generated image failure notice failed: ${W}`))}async function JQ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Q)=>[...Q]);await Promise.allSettled(J)}function gU($,Z,J,Q,Y,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=CZ($.taskBoard,J,Q,Y);let H=j1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(Y0($.currentTurn.cardId,E.tool(Z.i),H),$.currentTurn.taskLiveInserted)Y0($.currentTurn.cardId,E.taskBoardLive,c1($.taskBoard));Z2($)}function Z2($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function QQ($,Z,J,Q,Y,V=$.currentTurn){let X=V;if(!X)return;for(let[H,z]of Q){if(X.toolByUseId.has(H))continue;let W=z.batchSlot??null,G=z.input,K,_;if(W!=null){let D=Y.get(z.i)?.items[W];if(!D)continue;G=D.input,K=D.output,_=D.isError}else K=z.output??null,_=z.isError??!1;let L=K!=null,j=Y4(Z,E.tool(z.i));if(L&&!j)continue;if(W!=null){let D=Y.get(z.i)?.kind;if(!D)continue;let U=X.toolCount++,M={toolUseId:H,input:G,output:K,isError:_};X.toolBatches.set(U,{kind:D,items:[M]}),X.toolByUseId.set(H,{...z,i:U,batchSlot:0}),M0(J,NW(D,U,[M]),{type:"insert_before",targetElementId:T0(X)});continue}let q=p1(z.name);if(q){let D=q==="TaskCreate";if(D)X.taskUpdateI=null;else X.taskCreateI=null;let U=(D?X.taskCreateI:X.taskUpdateI)===null;if(U)if(D)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let M=D?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(H,{...z,i:M});let T=!L?"⏳":_?"❌":"✅",x=j1(M,$.taskBoard,{name:q,status:T},z.resolvedNote);U?M0(J,x,{type:"insert_before",targetElementId:T0(X)}):Y0(J,E.tool(M),x);continue}let P=X.toolCount++;X.toolByUseId.set(H,{...z,i:P});let N=!L?"⏳":_?"❌":"✅";M0(J,E$(P,z.name,z.input,K,N,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:T0(X)})}}var EW=O(()=>{pJ();u$();H$();r();h();M5()});async function xW($,Z,J,Q){let Y=$.pendingPermissions.get(Z);if(!Y)return B(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let V=$.proc;if(!V)return B(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let X=J==="deny"?"deny":"allow";try{V.sendPermissionResponse(Z,X,J==="allow_always"?{updatedPermissions:Y.permissionSuggestions}:void 0)}catch(W){return B(`session "${$.sessionName}": permission response ${Z} failed: ${W}`),{ok:!1,message:`权限决定发送失败: ${W instanceof Error?W.message:W}`}}$.pendingPermissions.delete(Z);let H=$.currentTurn,z=H?.toolByUseId.get(Y.toolUseId);if(H&&z){let W=p1(z.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,K=W?j1(z.i,$.taskBoard,{name:W,status:"❌"},G):E$(z.i,z.name,z.input,G,"❌");Y0(H.cardId,E.tool(z.i),K)}else{let G=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${G}** by ${Q||"匿名"}`;let K=W?j1(z.i,$.taskBoard,{name:W,status:"⏳"},z.resolvedNote):E$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);Y0(H.cardId,E.tool(z.i),K)}}if(B(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Y.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function SW($,Z){let J=$.currentTurn;if(!J){B(`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 Q=Z.tool_use_id;if(!Q){B(`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 Y=J.toolByUseId.get(Q);if(!Y){B(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Q} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Y.name==="AskUserQuestion"){let X=$.pendingAsks.get(Q);if(!X){B(`session "${$.sessionName}": AskUserQuestion ${Q} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(X.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Q}),X.currentIdx===void 0)ZQ($,Q);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Q,permissionSuggestions:Z.permission_suggestions}),B(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Q} tool=${Y.name}`);let V=YZ(Y.i,Y.name,Y.input,Z.request_id);if(Y0(J.cardId,E.tool(Y.i),V),J.userOpenId&&J.messageId){let X=z1(Y.name,Y.input),H=f1(Y.name),z=X&&X.length>30?X.slice(0,30)+"…":X,W=z?`\uD83D\uDD10 等审批: ${H} · ${z}`:`\uD83D\uDD10 等审批: ${H}`;(async()=>{g0(J.cardId),await J5(J.cardId,{config:{summary:{content:W}}}),await n1(J.messageId,[J.userOpenId])})()}}var CW=O(()=>{u$();H$();r();h();M5()});async function bW($=(Z)=>new H1({accountId:Z})){if(C2(p))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Q;try{Z=$(p),await Z.initialize("lodestar-login-check"),Q=await y1(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Y){J=Error(`默认账号登录检查失败:${q4(Y).message}`,{cause:Y})}if(!J){if(Q?.account===null||Q?.account?.type==="apiKey")J=Error("默认账号未登录 ChatGPT,请先发送不带备注的 codex-login 完成登录,再添加额外账号。");else if(Q?.account?.type!=="chatgpt")J=Error("默认账号登录检查失败:account/read 返回的账号状态无效")}if(Z)try{if(await Z.close(),Z.isAlive())throw Error("检查进程仍未退出")}catch(Y){J=Error([J?.message,`默认账号检查进程关闭失败:${q4(Y).message}`].filter(Boolean).join(";"),{cause:Y})}if(J)throw J}class kW{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Y)=>new H1({accountId:Y,login:!0}),Z=900000,J=(Y,V)=>{y.recordLogin(Y,V),p2(Y)},Q=1e4){this.createClient=$;this.waitMs=Z;this.recordLogin=J;this.stateWaitMs=Q}async start($,Z){if(this.stopping)throw Error("服务正在退出,无法开始登录");if(!Z.userOpenId)throw Error("无法确认登录发起者");if(this.attempts.has($))throw Error("该账号已有登录任务;使用 codex-login-cancel 取消后再登录");let J=RV($),Q;try{Q=this.createClient($)}catch(z){throw J(),z}let Y,V,X=new Promise((z,W)=>{Y=z,V=W});X.catch(()=>{});let H={owner:Z,client:Q,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:X,resolve:Y,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};H.notification=(z,W)=>{if(H.finishing||!H.loginRequested)return;if(z==="account/updated"){if(W?.authMode==="chatgpt"){if(H.authUpdated=!0,H.loginSucceeded)this.finish(H)}return}if(z!=="account/login/completed")return;if(!H.loginId){H.early.push(W);return}if(W?.loginId!==H.loginId)return;if(W?.success!==!0){this.finish(H,Error(typeof W?.error==="string"?W.error:"Codex 登录未成功"));return}if(H.loginSucceeded)return;if(H.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${H.authUpdated}`),H.timer)clearTimeout(H.timer);if(H.authUpdated)this.finish(H);else H.timer=setTimeout(()=>{this.finish(H,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},H.closed=(z)=>{this.finish(H,z)},Q.on("notification",H.notification),Q.on("closed",H.closed),Q.on("protocolError",H.closed),this.attempts.set($,H);try{await Q.initialize("lodestar-login"),H.loginRequested=!0;let z=await Q.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(H.loginId=z.loginId,H.finishing)throw await X,Error("登录已结束");H.timer=setTimeout(()=>{this.cancelAttempt(H,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let W of H.early)H.notification("account/login/completed",W);return H.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:X}}catch(z){return await this.finish(H,q4(z)),await X}}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(Q){J=Error(`${Z};取消请求失败:${q4(Q).message}`)}await this.complete($,J)}async finish($,Z){if($.finishing)return;if($.finishing=!0,$.timer)clearTimeout($.timer);let J;if(!Z)try{let Q=await $.client.request("account/read",{refreshToken:!1});if(Q?.account?.type!=="chatgpt"){let Y=typeof Q?.account?.type==="string"?Q.account.type:"null";throw Error(`设备码授权已完成,但账号状态校验失败(account/read.type=${Y});认证文件已保留`)}J=Q.account,this.recordLogin($.accountId,J)}catch(Q){Z=q4(Q)}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(Q){Z=Error([Z?.message,`登录进程关闭失败:${q4(Q).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 q4($){return $ instanceof Error?$:Error(String($))}var J2;var YQ=O(()=>{T$();f0();h();J2=new kW});class F4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=cU){let Q=await J.sendCard($,P$(Z,!0));if(!Q)throw Error("Codex 账号卡片发送失败");let Y=await J.convertMessageToCard(Q);return J.recordCardCreated(Y,1),new F4(Y,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=m9($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=m9($);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 Q=await this.deps.replaceElementChecked(this.cardId,E.codexAccountPanel,Z,{notifyCardFailure:!1}),Y=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:g9($)}}});if(!Q||!Y)throw Error(`Codex 账号卡片更新失败:内容 ${Q?"OK":"MISS"},状态 ${Y?"OK":"MISS"}`);if(J)await this.deps.dispose(this.cardId)}}var cU;var wW=O(()=>{r();u$();C0();H4();cU={sendCard:u,convertMessageToCard:F$,recordCardCreated:W$,replaceElementChecked:A0,patchSettingsChecked:R0,dispose:G$}});var XQ={};v$(XQ,{settleCodexAccountCards:()=>VQ,runCodexNamedHi:()=>lU,runCodexAccountCommand:()=>dU});import{createHash as uU}from"node:crypto";function r9($,Z){let J=$ instanceof Error?$.message:String($),Q=!/失败|未完全退出/.test(J)&&/登录已取消|服务退出/.test(J),Y=/过期|等待超过|expired/i.test(J),V=J.split(/[\n;]/)[0];return{phase:Q?"cancelled":Y?"expired":"error",name:Z,message:V.length>80?V.slice(0,77)+"…":V,...J!==V||V.length>80?{details:J}:{}}}async function yW($,Z){if(!await u($.chatId,P$(r9(Z))))throw Error("Codex 错误卡片发送失败")}async function lU($,Z){let J=await F4.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Q=y.find(Z),Y="";if(!await $.startWithCodexAccount(Q.id,{announce:!1,onStatus:(X)=>{Y=X}}))throw Error(Y||"指定账号启动失败");await J.finish({phase:"current",name:Q.name,current:Q.name,title:"已指定账号",hint:"本次手动指定 · 不参与自动排序"}),await $.showConsole()}catch(Q){await J.finish(r9(Q,Z))}}async function VQ(){let Z=(await Promise.allSettled([...Q2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function dU($,Z,J,Q,Y){if(Z==="reset"){await nU($,J,Y);return}let V={chatId:$.chatId,userOpenId:Q};if(Z==="login-cancel"){try{let W=J2.pending(V);if(!J&&W.length!==1)throw Error(W.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let G=J?y.find(J).id:W[0];await J2.cancel(G,V),await Q2.get(G)}catch(W){await yW($,W)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,H=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),z=await F4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号额度…":H?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let L=y.find(J);if(Q2.has(L.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:j}=y.remove(L.id);p2(L.id),await z.finish({phase:"deleted",name:L.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 L=J?Number(J):1;await w1();let j=$.codexAccountId(),q=H0("codex-sub",j),P=()=>$.currentProvider()==="codex"?$.currentModelLabel():q?.defaultModel,N=P(),D;if(!N)try{if(!q)throw Error("Codex 订阅来源尚未初始化");if(await q.refreshModels(),N=P(),!N)throw Error(q.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(x){D=`${y.get(j).name}:${x instanceof Error?x.message:String(x)}`}let U=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,M=N?await Q8.choose({model:N,effort:U}):null,T=M?SJ(M.candidates.flatMap((x)=>x.usage?[{account:x.account,usage:x.usage,fingerprint:x.identity.startsWith("record:")?null:x.identity}]:[])):await V5();if(D)B(`codex-accounts: scheduling MISS: ${D}`);await z.finish({phase:"accounts",total:T,currentId:j,...y.preferred($.sessionName)?{selectedId:y.selected($.sessionName)}:{},page:L,...M?{scheduling:{candidates:M.candidates,ultra:U==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:D,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");y.selectAuto($.sessionName),await z.finish({phase:"selected",name:"自动选择",current:y.get($.codexAccountId()).name,selected:"自动 · 最高分优先",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await z.finish({phase:"current",current:y.get($.codexAccountId()).name,selected:y.preferred($.sessionName)===null?"自动 · 最高分优先":y.get(y.selected($.sessionName)).name,hint:"周剩余份额 ÷ 重置小时 · codex-auto"});return}let L=y.find(J),j=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,P=y.get($.codexAccountId()).name;if($.currentProvider()==="codex")F1($.sessionName,"codex",j,q,"codex-sub");if(y.select($.sessionName,L.id),$.currentProvider()==="codex")$.selectedModel=j,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await z.finish({phase:"selected",name:L.name,current:P,selected:L.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Q)throw Error("无法确认登录发起者");if(H)await bW(),await z.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let W=y.ensure(J);if(v3(W.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(Q2.has(W.id))throw Error("登录结果正在更新,请稍等");let G=await J2.start(W.id,V);try{await z.update({phase:"waiting",flow:"login",name:W.name,verification:{url:G.verificationUrl,code:G.userCode},hint:`取消:codex-login-cancel${J?` ${W.name}`:""}`})}catch(L){throw await J2.cancel(W.id,V),L}let K=(async()=>{let L;try{L=await G.done}catch(q){await z.finish(r9(q,W.name));return}await z.update({phase:"checking",flow:"login",name:W.name,message:"授权完成,正在读取模型…"});let j;try{await w1();let q=H0("codex-sub",W.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 z.finish({phase:j?"warning":"success",flow:"login",name:W.name,email:L.email,plan:L.planType,...j?{title:"已登录 · 目录 MISS",details:j}:{},hint:`已加入自动选择 · 优先使用:codex-account ${W.id==="default"?"default":W.name}`})})();Q2.set(W.id,K);let _=()=>{if(Q2.get(W.id)===K)Q2.delete(W.id)};K.then(_,(L)=>{B(`codex-login: terminal card write failed: ${L}`),_()})}catch(W){B(`codex-${Z}: ${W}`),await z.finish(r9(W,X))}}async function nU($,Z,J){let Q;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 指定默认账号");Q=Z?y.find(Z):y.get(v0($.proc))}catch(W){B(`codex-reset: ${W}`),await yW($,W);return}let Y=await F4.open($.chatId,{phase:"checking",name:Q.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let W=uU("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await _X(Q.id,W)}catch(W){B(`codex-reset: ${W}`),await Y.finish(r9(W,Q.name));return}let X=iU[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(`
226
+ `);await Y.finish({...X,name:Q.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var Q2,iU;var O5=O(()=>{r();f0();YQ();e();CJ();k6();wW();H4();h();T$();Q2=new Map;iU={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as aU}from"node:fs";import{homedir as oU}from"node:os";import{join as IW}from"node:path";function tU(){return process.env.CLAUDE_CONFIG_DIR||IW(oU(),".claude")}function HQ(){try{let $=aU(IW(tU(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function Y2($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function rU($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function eU($){let Z=rU($);return Z&&Y2($)?Z:null}function fW($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function hW($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function $M($){let Z=Array.isArray($)?$:Array.isArray($?.limits)?$.limits:void 0;if(!Z)return{state:"network",reason:"GLM 额度响应缺少 limits 数组"};let J=Z.filter((G)=>G?.type==="TOKENS_LIMIT"||G?.type==="CREDIT_LIMIT"),Q=J.find((G)=>G?.unit===3&&G?.number===5),Y=J.find((G)=>G?.unit===6&&G?.number===1),V=Z.find((G)=>G?.type==="TIME_LIMIT"),X=(G)=>G?{percent:fW(G.percentage),resetsAt:hW(G.nextResetTime)}:null,H=X(Q),z=X(Y),W=V?{percent:fW(V.percentage),resetsAt:hW(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!H&&!z&&!W)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:H,weekly:z,monthly:W,fetchedAt:Date.now()}}async function N5($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:HQ(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let V=eU(Y);if(!V)return{state:"not_glm",baseUrl:Y||void 0};return sU.read(Q$("glm",V,Q),()=>ZM(V,Q))}async function ZM($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Q=new AbortController,Y=setTimeout(()=>Q.abort(),vW);try{let V=await X0(J,{headers:{Authorization:Z,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:Q.signal});if(!V.ok)return B(`glm-usage: quota/limit HTTP ${V.status}`),{state:V.status===429?"rate_limited":"network",reason:`HTTP ${V.status}`,retryAfterMs:R$(V.headers)};let X=await V.json(),H=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||H!==void 0&&String(H)!=="200"){let G=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[H===void 0?"":`code ${H}`,G===void 0?"":String(G)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(H)==="429"?"rate_limited":"network",reason:K,retryAfterMs:R$(V.headers)}}let z=X?.data??X,W=$M(z);if(W.state==="network")B(`glm-usage: quota/limit MISS: ${W.reason}`);return W}catch(V){let X=(V?.name==="AbortError"?`timeout ${vW}ms`:V?.message??String(V)).replaceAll(Z,"[redacted]");return B(`glm-usage: quota/limit fetch failed: ${X}`),{state:"network",reason:X}}finally{clearTimeout(Y)}}var vW=1e4,sU;var R5=O(()=>{u0();h();m$();sU=new n0});function QM($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function T5($,Z,J){try{let Q=await X0(QM($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(JM)});if(Q.ok)return"exists";if(Q.status===400){let Y=await Q.text();return Y.includes("1214")||Y.includes("不存在")||Y.includes("not exist")?"not_found":"no_verdict"}return B(`model-existence: ${J} HTTP ${Q.status}, no verdict`),"no_verdict"}catch(Q){return B(`model-existence: ${J} MISS (${Q?.message??Q})`),"no_verdict"}}var JM=15000;var zQ=O(()=>{u0();h()});function gW($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function YM($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function mW($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function VM($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function XM($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),V=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&V)Z[Y]=V}return Z}function WQ($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],..."retryAfterMs"in $?{retryAfterMs:$.retryAfterMs}:{},...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(gW($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(gW($.weekly,"weekly","周额度"));if($.monthly)Z.push(YM($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var GQ=O(()=>{e();R5();W4();J9();zQ();h();w4();j0({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Q=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Y=!!(J&&Q)&&Y2(J),V=$.model?.trim()||void 0,X=XM($.slots),H={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await vz(J,Q),G=[...new Set([...mW($.models),...mW($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:z4,defaultEffort:"max",origin:"custom"}));if(H.models=[...z,...G],!V)H.defaultModel=VM(H.models.map((K)=>K.model));for(let K of H.models){let _=y2("glm",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`glm refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...h0(z)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_AUTH_TOKEN=Q,X.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return G},resolveSpawnModel(z){return u3("glm",z)},async verifyModel(z){return T5(J,{Authorization:`Bearer ${Q}`},z)},async readUsage(){return WQ(await N5(J,Q))}};return H},setup:{commandSuffix:"glm",hint:($)=>`配置 ${$}:发送 \`glm-setup <api_key>\`(智谱国内站),或 \`glm-setup <base_url> <api_key>\`(指定平台)。Claude Code 和 DeepSeek Harness 共用该账号;校验失败保留原配置。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:glm-setup <api_key>,或 glm-setup <base_url> <api_key>;只填写 Key 本身,不加 Bearer 前缀。"};try{return{config:{agent:"claude",base_url:k4(Z.length===2?Z[0]:D2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await U2($.base_url??D2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!Y2(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var pW=O(()=>{e();W4();j0({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 X5(),!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 HM(){let $=Object.fromEntries(s3.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function zM($){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 cW=O(()=>{G0();h();e();W4();mJ();U1();j0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=HM(),J=$.model?.trim(),Q="Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用",Y,V={id:"claude-sub",kind:"claude-subscription",agent:"claude",display:$.display?.trim()||"Claude Code 订阅",enabled:$.enabled!==!1,models:[],defaultModel:J??"",modelCatalogState:$.enabled===!1?{status:"disabled",updatedAt:Date.now(),error:"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"}:{status:"idle",updatedAt:Date.now()},settingSources:["user","project","local"],claudeSettings:Z,validateClaudeAccount:zM,spawnEnv(X){return{...h0(X),...Z.env}},resolveSpawnModel(X){return X},async refreshModels(){if($.enabled===!1){V.enabled=!1,V.models=[],V.modelCatalogState={status:"disabled",updatedAt:Date.now(),error:"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"};return}V.enabled=!0,V.models=[],V.modelCatalogState={status:"loading",updatedAt:null};try{let X=await X5({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id});if(!X.length)throw Error("Claude Code 订阅模型目录为空");let H=[...Q0($.custom_models),...Q0($.models)];if(J&&!X.some((z)=>z.model===J)&&!H.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let z=X.find((W)=>W.model===(J??X[0].model));if(!D0($.effort)||z&&!z.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(z)z.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let H=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${H}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:H}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Y??=iz({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Y=void 0}),Y}};return V}})});function lW($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function WM($){let Z=(J)=>{let Q=J.match(/(\d+(?:\.\d+)?)/);return Q?Number(Q[1]):-1};return[...$].sort((J,Q)=>Z(Q)-Z(J))[0]??""}function GM($){let Z={};for(let J of($??"").split(",")){let Q=J.indexOf("=");if(Q<=0)continue;let Y=J.slice(0,Q).trim().toLowerCase(),V=J.slice(Q+1).trim();if((Y==="opus"||Y==="sonnet"||Y==="haiku")&&V)Z[Y]=V}return Z}function KM($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function dW($,Z){return(await KQ(new URL($).origin,Z)).map((Q)=>({model:Q,display:Q,efforts:z4,defaultEffort:"high"}))}async function KQ($,Z){let J=new URL($);if(!["https:","http:"].includes(J.protocol)||J.username||J.password||J.search||J.hash)throw Error("DeepSeek 需要无凭据和查询参数的 HTTP(S) API 根地址");return(await A$(`${J.toString().replace(/\/+$/,"")}/models`,Z,"DeepSeek models")).map((Y)=>{if(typeof Y.id!=="string"||!Y.id.trim())throw Error("DeepSeek models 模型 id 无效");return Y.id})}async function BQ($,Z){if(!Z.trim())return{kind:"balance",state:"no_credentials",windows:[]};let J;try{J=new URL($).origin}catch{return{kind:"balance",state:"network",windows:[],reason:"bad base_url"}}return _M.read(Q$("deepseek",J,Z),()=>jM(J,Z))}async function jM($,Z){try{let J=await X0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(BM)});if(!J.ok)return B(`deepseek readUsage MISS: HTTP ${J.status}`),{kind:"balance",state:J.status===429?"rate_limited":"network",windows:[],reason:`HTTP ${J.status}`,retryAfterMs:R$(J.headers)};let Q=await J.json(),V=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",H=V?.total_balance;if(!X||typeof H!=="string"&&typeof H!=="number"||String(H).trim()===""||!Number.isFinite(Number(H)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(H),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var uW="https://api.deepseek.com/anthropic",BM=1e4,_M;var _Q=O(()=>{u0();e();W4();J9();zQ();h();P2();m$();_M=new n0;j0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||uW,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,V=$.model?.trim()||void 0,X=GM($.slots),H={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await dW(J,Q),G=[...new Set([...lW($.models),...lW($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:z4,defaultEffort:"high",origin:"custom"}));if(H.models=[...z,...G],!V)H.defaultModel=WM(H.models.map((K)=>K.model));for(let K of H.models){let _=y2("deepseek",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`deepseek refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let G={...h0(z)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_API_KEY=Q,X.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=X.opus;if(X.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=X.sonnet;if(X.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=X.haiku;return G},resolveSpawnModel(z){return u3("deepseek",z)},async verifyModel(z){return T5(J,{"x-api-key":Q},z)},async readUsage(){if(!Q)return{kind:"balance",state:"no_credentials",windows:[]};return BQ(J,Q)}};return H},setup:{commandSuffix:"deepseek",hint:($)=>`配置 ${$}:发送 \`deepseek-setup <api_key>\`;Claude Code 和 DeepSeek Harness 共用该账号。自建端点用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Q=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Q}}},async validate($){await dW($.base_url??uW,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!KM(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function V2($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var jQ;var iW=O(()=>{jQ=[{rank:4,lab:"Tencent",model:"tencent/hy4-preview",effort:"high"},{rank:7,lab:"Google",model:"google/gemini-3.8-flash",effort:"high"},{rank:10,lab:"Meta",model:"meta/muse-spark-1.2",effort:"xhigh"},{rank:11,lab:"Xiaomi",model:"xiaomi/mimo-v2.5-pro",effort:"default"},{lab:"ByteDance",model:"bytedance-seed/seed-2-1-turbo",effort:"default"},{lab:"Meituan",model:"meituan/longcat-2.0",effort:"default"}]});function X2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function qQ($){return $ instanceof Error?$.message:String($)}function aW($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function P4($){return $.replace(/\[1m\]$/,"")}function D4($){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 FM($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Q=await X0(`${D4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(LM)});if(!Q.ok){let Y=await Q.text(),V="";if(Y.trim().startsWith("{"))try{let X=JSON.parse(Y);if(X2(X)&&X2(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new E5(Q.status,V.replaceAll(Z,"[redacted]"),R$(Q.headers))}return Q.json()}async function oW($,Z){let J=await A$(`${D4($)}/v1/models/user`,Z,"OpenRouter models"),Q=[],Y=new Set;for(let V of J){if(!X2(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!X2(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(V2(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Y.has(V.id))continue;let X=X2(V.reasoning)?V.reasoning:void 0,H=X?.supported_efforts,z=H===null||H===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(H)?[...new Set(H.filter((_)=>_!=="default"&&D0(_)))]:["default"],W=jQ.find((_)=>_.model===V.id),G=W?z.includes(W.effort)?W.effort:null:z[0]==="default"?"default":D0(X?.default_effort)&&z.includes(X.default_effort)?X.default_effort:null,K=y2("openrouter",V.id);Q.push({model:V.id,display:V.name,efforts:z,defaultEffort:G,context1m:K!==void 0&&K>=1e6||void 0}),Y.add(V.id)}if(!Q.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Q}function sW($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function PM($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return qM.read(Q$("openrouter",D4($),Z),()=>DM($,Z))}async function DM($,Z){try{let J=await FM($,Z,"credits");if(!X2(J)||!X2(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Q,total_usage:Y}=J.data;if(!sW(Q)||!sW(Y))throw Error("OpenRouter credits: total_credits/total_usage 缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Q-Y,currency:"USD"}}}catch(J){let Q=qQ(J);return B(`openrouter readUsage MISS: ${Q}`),{kind:"balance",state:J instanceof E5&&J.status===429?"rate_limited":"network",windows:[],reason:Q,...J instanceof E5?{retryAfterMs:J.retryAfterMs}:{}}}}var nW="https://openrouter.ai/api",LM=1e4,qM,LQ,E5;var tW=O(()=>{u0();G0();e();J9();h();iW();P2();m$();qM=new n0,LQ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};E5=class E5 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};j0({kind:"openrouter",configSectionId:"openrouter",build($,Z){let J=$.api_key||$.auth_token||$.base_url?$:Z,Q=J?.api_key?.trim()||J?.auth_token?.trim()||"",Y=J?.base_url?.trim()||nW,V=$.model?.trim()||"",X=$.models===void 0?jQ.map((z)=>z.model):aW($.models),H={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Q,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(z){if(V2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let W=H.modelSelection.availableModels.find((G)=>P4(G.model)===P4(z));if(!W||W.unavailableReason||!W.efforts.length)return"model-unavailable";return W.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(H.models=[],H.modelSelection.availableModels=[],!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await oW(Y,Q),W=z.find((K)=>K.model===P4(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=X.map((K)=>{let _=z.find((L)=>L.model===P4(K));if(!_)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:V2(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:K}});H.models=G,H.modelSelection.availableModels=z,H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let W=qQ(z);B(`openrouter refreshModels MISS: ${W}`),H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W}}},spawnEnv(z,W){if(!Q)throw Error("OpenRouter API key missing");let G=W||V;if(!G)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(V2(G))throw Error(`OpenRouter 已排除此厂商或自动路由: ${G}`);let K=h0(z);K.ANTHROPIC_BASE_URL=D4(Y),K.ANTHROPIC_AUTH_TOKEN=Q,K.ANTHROPIC_API_KEY="",K.CLAUDE_CODE_NO_MODEL_FALLBACK="1",K.ANTHROPIC_MODEL=G,K.ANTHROPIC_SMALL_FAST_MODEL=G,K.CLAUDE_CODE_SUBAGENT_MODEL=G,K.ANTHROPIC_DEFAULT_FABLE_MODEL=G;for(let _ of Object.values(LQ))K[_]=G;for(let _ of aW($.slots)){let L=_.indexOf("="),j=_.slice(0,L).trim(),q=_.slice(L+1).trim();if(L<1||!Object.hasOwn(LQ,j)||!q)throw Error(`OpenRouter slots 无效: ${_}`);if(V2(q)||!H.modelSelection.availableModels.some((P)=>!P.unavailableReason&&P4(P.model)===P4(q)))throw Error(`OpenRouter slot 模型不在账号目录中: ${q}`);if(H.modelEnvironmentRevision(q)!==H.modelEnvironmentRevision(G))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${q}`);K[LQ[j]]=q}return K},resolveSpawnModel(z){if(V2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return PM(Y,Q)}};return H},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:D4(Z[0])}:{}}}}catch(J){return{error:qQ(J)}}},async validate($){await oW($.base_url??nW,$.api_key??$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim(),J=$.ANTHROPIC_AUTH_TOKEN?.trim();if(!Z||!J)return null;try{let Q=D4(Z);if(new URL(Q).hostname!=="openrouter.ai")return null;return{base_url:Q,api_key:J}}catch{return null}}}})});function MM($){return $.trim().replace(/\[1m\]$/,"").toLowerCase().split("/").at(-1)??""}function eW($,Z="packy"){return UM[Z].includes(MM($))}var rW,UM;var $G=O(()=>{rW=["minimax-m3","claude-opus-5","claude-fable-5-1","qwen3.8-max-0902"],UM={packy:rW,"packy-secondary":rW,"packy-codex":["kimi-k3","grok-4.6"]}});function PQ($){return $.replace(/\[1m\]$/,"")==="gemini-3.8-flash"}function AM($,Z,J){let Q=Z==="claude"?c4:o4,Y=$.reasoning?.supported_efforts;if(Y!==void 0&&(!Array.isArray(Y)||!Y.length||!Y.every((z)=>typeof z==="string")))throw Error(`PackyAPI ${$.id} 的推理档位声明无效`);let V=Y===void 0?[...Q]:Q.filter((z)=>Y.includes(z));if(!V.length)throw Error(`PackyAPI ${$.id} 未声明当前 Agent 可用的推理档位`);let X=J.effort?.trim(),H=X||$.reasoning?.default_effort||(Y===void 0?Z==="claude"?"default":"medium":void 0);if(X&&!V.includes(X))throw Error(`PackyAPI effort 无效: ${X}`);return{model:$.id,display:$.display,efforts:V,defaultEffort:typeof H==="string"&&V.includes(H)?H:null}}var FQ="LODESTAR_PACKY_API_KEY",ZG,JG;var QG=O(()=>{G0();J1();vJ();$G();U1();h();m$();e();ZG={API_TIMEOUT_MS:"60000",CLAUDE_ENABLE_BYTE_WATCHDOG:"1",CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS:"45000",CLAUDE_CODE_MAX_RETRIES:"2",CLAUDE_CODE_RETRY_WATCHDOG:"0"};JG=[{id:"packy",agent:"claude",display:"PackyAPI"},{id:"packy-secondary",agent:"claude",display:"PackyAPI · 令牌2"},{id:"packy-codex",agent:"codex",display:"PackyAPI"}];for(let $ of JG){let{id:Z,agent:J,display:Q}=$,Y=J==="claude"?"anthropic":"openai-response",V=(X)=>X.protocols.includes(Y)||J==="claude"&&PQ(X.id);j0({kind:Z,configSectionId:Z,build(X){let H=X.api_key?.trim()||X.auth_token?.trim()||"",z=w$(X.base_url?.trim()||r1),W=X.management_url?.trim()?w$(X.management_url):G4(z),G=X.management_token?.trim()||"",K=X.management_user_id?.trim()||"",_=!!(G||K||X.management_url?.trim()||X.billing_source?.trim()),L=X.model?.trim(),j=X.models===void 0?void 0:Q0(X.models),q=new Set([...Q0(X.custom_models),...j??[]]),P=(M)=>eW(M,Z),N=[],D=(M)=>{let T=N.find((x)=>x.id===M);if(T&&!V(T)&&!q.has(M))throw Error(`PackyAPI ${M} 未声明 ${Y};确认兼容后可显式补录`)},U={id:Z,kind:Z,agent:J,display:X.display?.trim()||Q,enabled:!!H&&X.enabled!==!1,models:[],defaultModel:L??"",modelSelection:{mode:"allowlist",modelIds:j??[],availableModels:[]},..._?{usageAccount:{id:Q$("packy-account",W,K),label:"PackyAPI"}}:{},modelCatalogState:{status:H&&X.enabled!==!1?"idle":"disabled",updatedAt:Date.now()},...J==="claude"?{modelEnvironmentRevision(M){return PQ(M)?JSON.stringify(ZG):"native-retries"}}:{},...J==="codex"?{codexApiProvider:{id:"packy",name:"PackyAPI",baseUrl:`${z}/v1`,envKey:FQ}}:{},async refreshModels(){if(U.models=[],N=[],!U.enabled){U.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}U.modelCatalogState={status:"loading",updatedAt:null};try{N=await wJ(z,H);let M=N.filter((b)=>V(b)||q.has(b.id));if(!M.length&&!q.size)throw Error(`PackyAPI 此令牌没有声明支持 ${Y} 的模型,请检查分组和模型限制`);let T=M.map((b)=>({...AM(b,J,X),...!b.protocols.includes(Y)&&q.has(b.id)?{origin:"custom"}:{}}));for(let b of q){if(T.some((v)=>v.model.toLowerCase()===b.toLowerCase()))continue;T.push({model:b,display:b,origin:"custom",...p9(U,X)})}if(L&&!T.some((b)=>b.model===L)){if(N.find((v)=>v.id===L))throw Error(`PackyAPI ${L} 未声明 ${Y},确认兼容后请显式补录`);if(!q.has(L))throw Error(`PackyAPI 默认模型不在目录中且未补录: ${L}`)}let x=j??T.filter((b)=>b.origin==="custom"||P(b.model)).map((b)=>b.model);if(j===void 0&&L&&!x.some((b)=>b.toLowerCase()===L.toLowerCase()))x.unshift(L);let w=x.map((b)=>T.find((v)=>v.model===b)??{model:b,display:b,efforts:[],defaultEffort:null,unavailableReason:"账号目录未返回该模型"});U.modelSelection.availableModels=T,U.models=w,U.modelSelection.modelIds=w.map((b)=>b.model),U.defaultModel=L??w.find((b)=>!b.unavailableReason)?.model??[...q][0]??"",U.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(M){U.models=[],N=[];let T=w0(M,[H]);B(`${Z} refreshModels MISS: ${T}`),U.modelCatalogState={status:"failed",updatedAt:Date.now(),error:T}}},resolveSpawnModel(M){return D(M),M},spawnEnv(M,T){if(!H)throw Error("PackyAPI API key missing");let x=T||U.defaultModel;if(!x)throw Error("PackyAPI 尚未选择模型");D(x);let w=h0(M);if(delete w[FQ],J==="codex"){for(let v of["CODEX_API_KEY","OPENAI_API_KEY","OPENAI_BASE_URL","CODEX_ACCESS_TOKEN","OPENAI_FEDERATION_RULE_ID","OPENAI_IDENTITY_TOKEN_FILE","OPENAI_WORKLOAD_IDENTITY_CONTEXT"])delete w[v];return w[FQ]=H,w}if(w.ANTHROPIC_BASE_URL=z,w.ANTHROPIC_AUTH_TOKEN=H,w.ANTHROPIC_API_KEY="",w.CLAUDE_CODE_NO_MODEL_FALLBACK="1",PQ(x))Object.assign(w,ZG);w.ANTHROPIC_MODEL=x,w.ANTHROPIC_SMALL_FAST_MODEL=x,w.CLAUDE_CODE_SUBAGENT_MODEL=x;for(let v of["OPUS","SONNET","HAIKU","FABLE"])w[`ANTHROPIC_DEFAULT_${v}_MODEL`]=x;let b={opus:"OPUS",sonnet:"SONNET",haiku:"HAIKU",fable:"FABLE"};for(let v of Q0(X.slots)){let[C,f,m]=v.split("=");if(!C||!Object.hasOwn(b,C)||!f||m!==void 0)throw Error(`PackyAPI slots 无效: ${v}`);if(!V1(U).some((l)=>l.model===f))throw Error(`PackyAPI slot 模型不在当前来源: ${f}`);D(f),w[`ANTHROPIC_DEFAULT_${b[C]}_MODEL`]=f}return w},readUsage(){return _?yJ(W,G,K):Iz(z,H)}};return U},setup:{commandSuffix:Z,hint:()=>`发送 \`${Z}-setup [base_url] <api_key>\` 配置${Q}。${Z==="packy-codex"?"与 PackyAPI 主账号共用凭据。":""}`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length<1||H.length>2||/^https?:\/\//i.test(H.at(-1)))return{error:`用法: ${Z}-setup [base_url] <api_key>`};try{return{config:{agent:J,api_key:H.at(-1),base_url:w$(H.length===2?H[0]:r1)}}}catch(z){return{error:w0(z,[H.at(-1)])}}},async validate(X){if(!(await wJ(X.base_url??r1,X.api_key??X.auth_token??"")).some(V)&&!Q0(X.custom_models).length&&!Q0(X.models).length)throw Error(`此令牌没有声明支持 ${Y} 的模型`)}},...Z==="packy-codex"?{}:{usageSetup:{commandSuffix:`${Z}-balance`,hint:()=>`发送 \`${Z}-balance-setup [management_url] <user_id> <system_token>\` 配置真实余额;共用已有账号用 \`${Z}-balance-setup share <source_id>\`。`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length===2&&H[0]==="share"){if(!JG.some((G)=>G.id===H[1])||H[1]===Z)return{error:"请指定另一个已配置的 PackyAPI 来源:packy、packy-secondary 或 packy-codex"};return{config:{billing_source:H[1],management_token:"",management_user_id:"",management_url:""}}}if(H.length<2||H.length>3)return{error:`用法:${Z}-balance-setup [management_url] <user_id> <system_token>,或 ${Z}-balance-setup share <source_id>`};let z=H.at(-2),W=H.at(-1);if(!/^[1-9]\d*$/.test(z)||!Number.isSafeInteger(Number(z)))return{error:"用户 ID 必须是正整数"};try{return{config:{billing_source:"",management_token:W,management_user_id:z,management_url:H.length===3?w$(H[0]):""}}}catch(G){return{error:w0(G,[W])}}},async validate(X){let H=X.management_url||G4(X.base_url||r1),z=await yJ(H,X.management_token||"",X.management_user_id||"",!0);if(z.state!=="ok")throw Error(z.reason||"PackyAPI 真实账户余额查询失败")}}}})}});var YG=O(()=>{e();G0();p4();V0();_Q();U1();j0({kind:"deepseek-harness",configSectionId:"deepseek-harness",build($){let Z=$.api_key?.trim()??"",J=$.base_url?.trim()||"https://api.deepseek.com",Q={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(Y){let V=Q9(Y);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(!Q.enabled){Q.models=[],Q.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Q.modelCatalogState={status:"loading",updatedAt:null};try{let Y=await N2({cwd:q2,env:Q.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...Q0($.models),...Q0($.custom_models)]});if(!Array.isArray(Y)||!Y.length)throw Error("DeepSeek Harness model catalog is empty");for(let X of Y)if(!X.model||!X.efforts.length||!X.efforts.every(q0)||!q0(X.defaultEffort)||!X.efforts.includes(X.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${X.model}`);let V=$.model?.trim()||Y.find((X)=>X.isDefault)?.model;if(!V||!Y.some((X)=>X.model===V))throw Error("DSH default model is not in its catalog");Q.models=Y.map(({model:X,display:H,efforts:z,defaultEffort:W,isCustom:G})=>{let K=$.effort?.trim();if(K&&(!q0(K)||!z.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:H,efforts:z,defaultEffort:K?K:W,origin:G?"custom":"upstream"}}),Q.defaultModel=V,Q.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(Y){throw Q.models=[],Q.modelCatalogState={status:"failed",updatedAt:Date.now(),error:Y instanceof Error?Y.message:String(Y)},Y}},resolveSpawnModel(Y){return V1(Q).find((V)=>V.model===Y)?.model},readUsage(){return Z?BQ(J,Z):Promise.resolve({kind:"balance",state:"no_credentials",windows:[]})}};return Q},setup:{commandSuffix:"deepseek-harness",hint:()=>"DeepSeek 账号由 Claude Code 和 DeepSeek Harness 共用。发送 `deepseek-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||/^https?:\/\//i.test(Z.at(-1)))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]}:{}}}},async validate($){await KQ($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function x5($){let Z=new URL($);if(!Y2(Z.origin)||Z.protocol!=="https:"||Z.username||Z.password||Z.search||Z.hash)throw Error("DSH GLM 需要智谱或 Z.ai 的 Coding Plan HTTPS 端点;地址中不能包含凭据或查询参数");return Z.pathname="/api/coding/paas/v4",Z.search="",Z.hash="",Z.toString().replace(/\/$/,"")}async function VG($,Z){return(await A$(`${$}/models`,Z,"GLM Coding Plan models")).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 XG=O(()=>{P2();S0();G0();e();p4();V0();R5();GQ();U1();j0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=g.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Q=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Q&&Y2(Q)?{api_key:J,base_url:x5(Q)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Q=x5($.base_url?.trim()||Z?.base_url?.trim()||"https://open.bigmodel.cn/api/coding/paas/v4"),Y=new URL(Q).hostname.endsWith("bigmodel.cn")?"zai-coding-cn":"zai",V,X={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(H){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=Q9(H);if(z.LODESTAR_DSH_PROVIDER=Y,z.LODESTAR_DSH_GLM_API_KEY=J,z.LODESTAR_DSH_BASE_URL=Q,z.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel,V)z.LODESTAR_DSH_MODELS=JSON.stringify(V);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(X.models=[],V=void 0,!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let H=await VG(Q,J),z=[...H];for(let G of[...Q0($.models),...Q0($.custom_models)])if(!z.some((K)=>K.model.toLowerCase()===G.toLowerCase()))z.push({model:G,display:G});if(V=z.map((G)=>G.model),!$.model?.trim()){let G=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...H].sort((K,_)=>G(_.model)-G(K.model))[0].model}let W=await N2({cwd:q2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=z.map((G)=>{let K=W.find((q)=>q.model===G.model),_=p9(X,$),L=K?K.efforts.filter(q0):_.efforts,j=$.effort?.trim()||K?.defaultEffort||_.defaultEffort;return{...G,display:K?.display??G.display,efforts:L,defaultEffort:q0(j)&&L.includes(j)?j:null,origin:H.some((q)=>q.model===G.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H instanceof Error?H.message:String(H)},H}},resolveSpawnModel(H){return V1(X).find((z)=>z.model===H&&!z.unavailableReason)?.model},async readUsage(){return J?WQ(await N5(Q,J)):{state:"no_credentials",windows:[]}}};return X},setup:{commandSuffix:"dsh-glm",hint:()=>"GLM Coding Plan 账号由 Claude Code 和 DeepSeek Harness 共用。发送 `glm-setup <api_key>` 配置两边;`dsh-glm-setup [base_url] <api_key>` 同样更新共享账号。",parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:dsh-glm-setup [base_url] <api_key>"};try{return{config:{agent:"dsh",api_key:Z.at(-1),base_url:x5(Z.length===2?Z[0]:"https://open.bigmodel.cn/api/coding/paas/v4")}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await VG(x5($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var zG={};v$(zG,{tokenSourceSpawnRevision:()=>HG,buildTokenSourcesFromConfig:()=>DQ});import{createHash as OM}from"node:crypto";function DQ(){let $=HQ(),Z=Object.fromEntries(k1().flatMap((H)=>{let z=H.detect?.fromSettingsEnv($);return H.configSectionId&&z?[[H.configSectionId,z]]:[]})),J=u9(g.token_sources??{},Z),Q=k1().map((H)=>{let z=H.configSectionId?J[H.configSectionId]??{}:{},W=H.configSectionId?Z[H.configSectionId]??null:null,G=H5(H.build(z,W),z);return G.spawnRevision=HG(H.kind,z,W),G}),Y=Q.find((H)=>H.kind==="claude-native");if(Y){let H=Q.some((z)=>z.agent==="claude"&&z.enabled&&z.kind!=="claude-native"&&z.kind!=="claude-subscription");Y.enabled=!H,Y.modelCatalogState={status:Y.enabled?"idle":"disabled",updatedAt:Date.now()}}T6();for(let H of Q)O6(H);let X=Q.find((H)=>H.enabled&&g.token_sources?.[H.id]?.default===!0)??Q.find((H)=>H.enabled);if(X)R6(X.id);return Q.length}function HG($,Z,J){let Q=(Y)=>({agent:Y?.agent,auth:Y?.auth,base_url:Y?.base_url,auth_token:Y?.auth_token,api_key:Y?.api_key,bin:Y?.bin,model:Y?.model,effort:Y?.effort,slots:Y?.slots});return OM("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var UQ=O(()=>{S0();e();R5();U1();l9();kJ();GQ();pW();cW();_Q();tW();QG();YG();XG()});import{readFileSync as NM}from"node:fs";function RM($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function TM($,Z){let J=[`[token_source.${$}]`],Q=(Y,V)=>{if(V!==void 0)J.push(`${Y} = "${RM(V)}"`)};if(Q("agent",Z.agent),Z.enabled!==void 0)J.push(`enabled = ${Z.enabled}`);if(Q("display",Z.display),Q("auth",Z.auth),Q("base_url",Z.base_url),Q("auth_token",Z.auth_token),Q("api_key",Z.api_key),Q("management_token",Z.management_token),Q("management_user_id",Z.management_user_id),Q("management_url",Z.management_url),Q("billing_source",Z.billing_source),Q("bin",Z.bin),Q("model",Z.model),Q("effort",Z.effort),Q("models",Z.models),Q("hidden_models",Z.hidden_models),Q("custom_models",Z.custom_models),Q("slots",Z.slots),Q("usage",Z.usage),Z.default!==void 0)J.push(`default = "${Z.default}"`);return J.join(`
227
+ `)}function EM($,Z){xM({[$]:Z})}function xM($){if(!Object.keys($).length)return;let Z=NM(E0,"utf8"),J=u4().token_sources,Q={};for(let[z,W]of Object.entries($)){let G=hJ(J,z,W);J={...J,...G},Object.assign(Q,G)}u9(J);let Y=new Set(Object.keys(Q).map((z)=>`[token_source.${z}]`)),V=Z.split(`
228
+ `),X=!1,H=[];for(let z of V){let W=z.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(W)X=Y.has(W);if(!X)H.push(z)}while(H.length&&H[H.length-1]==="")H.pop();l0(E0,H.join(`
229
229
  `)+`
230
230
 
231
- `+Object.entries(Y).map(([z,G])=>$U(z,G)).join(`
231
+ `+Object.entries(Q).map(([z,W])=>TM(z,W)).join(`
232
232
 
233
233
  `)+`
234
- `)}function l9($){let Z=uG.then($);return uG=Z.then(()=>{},()=>{}),Z}async function d9($,Z,J){ZU($,Z),J?.(),ZV(),XY(),await r4()}function lG($,Z){return l9(()=>d9($,Z))}function dG($,Z){return l9(async()=>{let J=!1;try{if(!$.configSectionId||!$.setup)throw Error("此来源不支持配置命令");let Y=h4().token_sources,Q={...Y,...TJ(Y,$.configSectionId,Z)};await $.setup.validate(J7(Q)[$.configSectionId]),await d9($.configSectionId,Z,()=>{J=!0})}catch(Y){throw new F7(Y,J)}})}function iG($,Z,J,Y="default"){return l9(async()=>{let Q=V0($,Y);if(!Q?.enabled||!Q.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Q.modelSelection.modelIds.filter((_)=>Q.models.find((L)=>L.model===_)?.origin!=="custom");if(J==="add"){if(Q.modelCatalogState?.status!=="ready")throw Error(Q.modelCatalogState?.error??"模型目录未就绪");let _=Q.modelSelection.availableModels.find((L)=>L.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 X=J==="add"?[...V,Z]:V.filter((_)=>_!==Z),H=v.token_sources[$],z=Q.modelSelection.mode==="catalog",G=q0(H?.hidden_models),W=z?{hidden_models:(J==="remove"?[...new Set([...G,Z])]:G.filter((_)=>_!==Z)).join(",")}:{models:X.join(",")};await d9($,W);let K=V0($,Y);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function nG($,Z,J="default"){return l9(async()=>{let Y=Z.trim();if(!Y||Y.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Y))throw Error("模型 ID 无效,请只填写一个完整模型名");let Q=V0($,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 X=v.token_sources[$];await d9($,{custom_models:[...q0(X?.custom_models),Y].join(",")});let H=V0($,J);if(H?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${H?.modelCatalogState?.error??"MISS"}`)})}function aG($,Z,J="default"){return l9(async()=>{let Y=V0($,J),Q=Y?.modelSelection?.availableModels.find((G)=>G.model===Z);if(!Y?.enabled||Q?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=v.token_sources[$]??{},X=(G)=>G?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),H={custom_models:q0(V.custom_models).filter((G)=>!X(G)).join(","),hidden_models:q0(V.hidden_models).filter((G)=>!X(G)).join(","),...V.models!==void 0?{models:q0(V.models).filter((G)=>!X(G)).join(",")}:{},...X(V.model)?{model:"",effort:""}:{},...V.slots?{slots:V.slots.split(",").filter((G)=>!X(G.slice(G.indexOf("=")+1))).join(",")}:{}};await d9($,H);let z=V0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var uG,F7;var zY=O(()=>{Q0();S0();HY();Z0();x0();d1();v9();uG=Promise.resolve();F7=class F7 extends Error{saved;constructor($,Z){super($ instanceof Error?$.message:String($),{cause:$});this.saved=Z}}});var D7={};S$(D7,{runTokenSourceSetup:()=>QU,runClaudeSubscriptionCommand:()=>JU,onTokenSourceEnable:()=>YU});async function JU($,Z){if(Z&&Z!=="on"&&Z!=="off"){await E($.chatId,`用法:${"claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"}`);return}if(Z)try{await lG("claude-sub",{enabled:Z==="on"})}catch(H){let z=H instanceof Error?H.message:String(H);B(`claude-sub ${Z} failed: ${z}`),await E($.chatId,`❌ Claude Code 订阅开关更新失败:${z}`);return}let Y=e0("claude-sub"),Q=v.token_sources["claude-sub"]?.enabled!==!1,V=Y?.modelCatalogState,X=[`Claude Code 订阅:${Q?"已启用":"已禁用"}(Lodestar 全局)`];if(Q&&(!Y?.enabled||V?.status!=="ready"))X.push(`可用性 MISS:${V?.error??(V?.status==="loading"||V?.status==="idle"?"模型目录尚未就绪,请发送 md 刷新":"订阅来源不可用")}`);if(X.push("所有群共用;保留本机登录态。"),!Q)X.push("禁止新任务,已在执行的任务继续完成。");X.push("claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"),await E($.chatId,X.join(`
235
- `))}async function YU($,Z){let J=e0(Z);if(!J){await E($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled&&J.modelCatalogState?.status!=="failed"){await E($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=O1().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup){let Q=J.modelCatalogState?.status==="failed"?`${J.display} 当前不可用:${K2(J.modelCatalogState.error??"MISS")}
236
- `:"";await E($.chatId,Q+Y.setup.hint(J.display))}else if(J.kind==="codex-subscription"){if(!await u($.chatId,P$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await E($.chatId,v.token_sources["claude-sub"]?.enabled===!1?"Claude Code 订阅已在 Lodestar 中禁用。发送 `claude-sub on` 启用,所有群共用,本机登录态保持不变。":J.modelCatalogState?.error??"请在运行 Lodestar 的本机执行 `claude auth login` 登录 Claude 订阅,完成后发送 `md` 刷新。");else if(J.kind==="claude-native")await E($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function QU($,Z,J){let Y=O1().find((X)=>X.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}let V=!1;try{await dG(Y,Q.config),V=!0;let X=e0(Y.configSectionId),H=Tz(Y.configSectionId).map((G)=>e0(G)),z=H.find((G)=>G?.modelCatalogState?.status!=="ready");if(z||H.some((G)=>!G)){let G=K2(z?.modelCatalogState?.error??"模型目录尚未就绪",[Q.config.api_key,Q.config.auth_token]);await E($.chatId,`❌ ${X?.display??Z} 凭据校验通过、配置已保存,但暂不可用:${G}
237
- 处理后发送 md 刷新。`);return}await E($.chatId,`✅ ${X.display} 校验通过,配置已保存。${H.length>1?"Claude Code 和 DeepSeek Harness 共用该账号。":""}发送 md 选择模型。`)}catch(X){let H=V||X instanceof F7&&X.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",z=K2(X,[Q.config.api_key,Q.config.auth_token]);await E($.chatId,`❌ ${H}:${z}`)}}var M7=O(()=>{r();Z0();zY();J4();S0();f();v9()});async function oG($,Z,J="",Y){let Q=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Q){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (B7(),oJ));return await K($,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:K}=await Promise.resolve().then(() => (B7(),oJ));return await K($,V[1].toLowerCase(),(V[2]??"").trim(),J,Y),!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (M7(),D7));return await K($,(X[1]??"").trim().toLowerCase()),!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 z=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(z)return await $.runFileDeliveryCommand((z[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let G=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(G){let{runTokenSourceSetup:K}=await Promise.resolve().then(() => (M7(),D7));return await K($,G[1].trim().toLowerCase(),(G[2]??"").trim()),!0}let W=VU.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 K=!$.isRunning(),_=$.backendLabel(),L=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${_}`)):null,j=$.withModel(`\uD83D\uDE80 启动 ${_}`);if(!(K?await $.start({announce:!L,onStatus:(F)=>{j=F,$.setStatusCard(L,F)}}):!0))return await $.closeStatusCard(L,j.startsWith("❌")?j:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(L)await $.closeStatusCard(L,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:R}=await Promise.resolve().then(() => (J4(),Dz));if(!await u($.chatId,R({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(L)return await $.replaceStatusCardWithConsole(L,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(L,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let L=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!L,onStatus:(j)=>$.setStatusCard(L,j)}),await $.closeStatusCard(L,"\uD83D\uDED1 已取消额度恢复")}catch(j){throw await $.closeStatusCard(L,`❌ ${N(j)}`),j}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(K)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await E($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let L=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(L)await $.closeStatusCard(L,"⚪ 无正在执行的 turn");else await E($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let _=new Set;for(let[L,j]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(j)k0(L,j);d0(L,"CrossMark"),_.add(L)}for(let L of $.pendingMidTurnMsgs)if(L.msgId&&!_.has(L.msgId))d0(L.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 K=$.isRunning(),_=$.backendLabel($.proc?.provider??$.currentProvider()),L=K?`\uD83D\uDED1 停止 ${_}`:"⚪ session 当前未运行",j=await $.openStatusCard("kill",L,K?"red":"grey"),q=null,F=K?`✅ ${_} 已终止`:`⚪ ${_} 未运行`;try{await $.stop("已终止",{announce:!j,onStatus:(R)=>{$.setStatusCard(j,R)}})}catch(R){q=R,F=$.isRunning()?`❌ ${_} 未确认终止: ${N(R)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${_} 停止收尾失败: ${N(R)}`}finally{try{await $.closeStatusCard(j,F)}catch(R){B(`session "${$.sessionName}": kill status card close failed: ${N(R)}`),await w($.chatId,`${F}
238
- ⚠️ kill 状态卡片终态写入失败: ${N(R)}`)}}if(q&&!j)await w($.chatId,F)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?O0($.lastSessionId):"",_=$.backendLabel($.proc?.provider??$.currentProvider()),L=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${_}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${_}`),j=await $.openStatusCard("restart",L),q=L,F=await $.restart(!0,{announce:!j,onStatus:(D)=>{q=D,$.setStatusCard(j,D)}}),R=F?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(j,F?$.withModel(R):R)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let K=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(K)await $.closeStatusCard(K,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let K=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),_="\uD83E\uDDF9 清空并启动新会话",L=await $.restart(!1,{announce:!K,onStatus:(j)=>{_=j,$.setStatusCard(K,j)}});await $.closeStatusCard(K,L?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):_.startsWith("❌")?_:"❌ 清空失败")}return!0}}var VU;var sG=O(()=>{r();f();VU=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 zU($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",G),$.off("error",W)},X=(_)=>{if(Z)return;Z=!0,V(),J(_)},H=(_)=>{if(Z)return;Z=!0,V(),Y(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Q&&_.threadId!==Q)return;X(_)},G=()=>H(Error(`${$.provider} process exited before context compaction completed`)),W=(_)=>H(_ instanceof Error?_:Error(String(_))),K=new Promise((_,L)=>{J=_,Y=L});return $.on("context_compacted",z),$.once("exit",G),$.once("error",W),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function GU($,Z){let J=[],Y=new Set,Q=(H,z)=>{let G=z.threadId??Z;if(G&&H.threadId&&H.threadId!==G)return!1;if(z.turnId)return H.turnId===z.turnId;return!0},V=(H)=>{for(let z=J.length-1;z>=0;z--){let G=J[z];if(G&&Q(G,H))return G}return null},X=(H)=>{if(Z&&H.threadId&&H.threadId!==Z)return;let z={usage:H.usage,contextWindow:H.contextWindow,threadId:H.threadId,turnId:H.turnId};J.push(z);for(let G of[...Y])if(Q(z,G.notice))G.finish(z)};return $.on("token_usage",X),{waitFor(H,z){let G=V(H);if(G)return Promise.resolve(G);return new Promise((W)=>{let K=null,_={notice:H,finish:(L)=>{if(K)clearTimeout(K);Y.delete(_),W(L)}};K=setTimeout(()=>_.finish(null),z),Y.add(_)})},cancel(){$.off("token_usage",X);for(let H of[...Y])H.finish(null)}}}function WU($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=t3($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=r3($.contextWindow);return` · \uD83E\uDDE0 ${BX(Z,J)} (${e3(Z,J)})`}async function tG($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let G=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(G)await $.closeStatusCard(G,"⚪ 后端未运行,compact 无效");else await E($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let G=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(G)await $.closeStatusCard(G,"⚠️ 先 stop 当前 turn,再 compact");else await E($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let G=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(G)await $.closeStatusCard(G,"⏳ 上下文压缩已在进行中");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"),X=async(G)=>{if(V)await $.closeStatusCard(V,G);else await E($.chatId,G)},H=zU(J),z=GU(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let G=await H.promise,W=await z.waitFor(G,HU),K=G.threadId?` thread=${O0(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${WU(W)}`))}catch(G){if(H.cancel(),G instanceof D1)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${N(G)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var HU=1500;var rG=O(()=>{j0();r()});import{randomUUID as BU}from"node:crypto";function eG($,Z){return{ok:!1,message:Z,card:M8($.sessionName,!1,Z)}}async function WY($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return eG($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${N(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof D2&&J.error.confirmedModel!==null?Z.model:null,Z.confirmedEffort=J.ok?Z.effort:null;let Y=J.ok?null:N(J.error);if(J.ok)try{if($.modelSelectionNeedsProcessStop(Z.provider,Z.sourceId??$.selectedTokenSourceId,Z.model))throw Error("等待期间进程账号配置已变化,请 stop 后重新选择");await $.applyModelSelectionUnlocked(Z.provider,Z.model,Z.effort,Z.sourceId)}catch(Q){Y=`模型和思考档位已应用,但保存选择失败:${N(Q)}`}if(Y!==null)return Z.phase="failed",Z.error=`${Y}。本次完整设置未保存,后续输入暂停;请重新发送 md 完成选择,或 restart 恢复已保存的设置。`,B(`session "${$.sessionName}": model settings incomplete: ${Z.error}`),eG($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${s0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:_9({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:_Y($,Z.provider)})}}async function _U($,Z,J,Y,Q,V,X){let H,z=new Promise((j)=>{H=j}),G={proc:Z,provider:Z.provider,model:J,effort:Q,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(j){G.cancelled=j,H({ok:!1,error:Error(j)})}};$.modelSettingsChange=G;let W=Promise.resolve().then(()=>Z.setModelSettings(Y,Q)).then(()=>({ok:!0}),(j)=>({ok:!1,error:j})),K=Promise.race([W,z]),_=Symbol("model-settings-pending"),L;try{let j=await Promise.race([K,new Promise((F)=>{L=setTimeout(()=>F(_),20000)})]);if(j!==_)return await WY($,G,j);let q=`正在等待 ${s0(Z.provider)} 确认 ${J} / ${Q},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:q,card:M8($.sessionName,!0,q),completion:K.then((F)=>$.finishModelSettingsChange(G,F))}}finally{clearTimeout(L)}}function jU($){let Z=$.currentTokenSource();return $$().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 KY($,Z,J=Z.models){let Y=$.currentModelLabel(),Q=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let H=V&&Y===X.model;return{provider:Z.agent,sourceId:Z.id,model:X.model,displayName:X.display,description:X.unavailableReason??(X.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:X.unavailableReason,origin:X.origin,enabled:!0,isDefault:!1,selected:H,efforts:X.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===X.defaultEffort,selected:H&&Q===z}))}})}async function $W($){await r4();let Z=BU(),J=jU($);$.modelPanels.set(Z,{models:[]});let Y=await u($.chatId,ZZ({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 BY($,Z,J=""){let Y=Z.trim(),Q=$.tokenSource(Y);if(!Q)return{ok:!1,message:`未知账号: ${Y}`};if(!Q.enabled)return{ok:!1,message:Q.modelCatalogState?.error??`${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 X=KY($,Q),H=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Y,messageId:H,mode:"select",editable:!!Q.modelSelection,sourceRevision:Q.spawnRevision}),U7($,V,Y,0)}async function U7($,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/GY));if(!Number.isInteger(Y)||Y<0||Y>=V)return{ok:!1,message:"模型页码无效"};return Q.models=Q.catalog.slice(Y*GY,(Y+1)*GY),Q.page=Y,Q.totalPages=V,{ok:!0,message:"",card:JZ({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 ZW($,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((X)=>X.origin!=="custom"&&!Q.modelSelection.modelIds.includes(X.model)&&(Q.modelSelection.mode==="catalog"||!X.unavailableReason&&X.efforts.length>0));return $.modelPanels.set(Z,{models:[],catalog:KY($,Q,V),sourceId:J,messageId:Y.messageId,mode:"add",editable:!0,sourceRevision:Q.spawnRevision}),U7($,Z,J,0)}async function JW($,Z,J,Y,Q){let V=$.modelPanels.get(Z),X=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!X?.modelSelection||V.sourceRevision!==X.spawnRevision||V.mode!==(Q==="add"?"add":"select")||!V.models.some((H)=>H.model===Y))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Q==="delete"){let H=[...q$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Y.replace(/\[1m\]$/,""));if(H.length)return{ok:!1,message:`补录模型仍被会话 ${H.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Q==="delete")await aG(J,Y,$.codexAccountId());else await iG(J,Y,Q,$.codexAccountId());for(let z of q$.all)for(let[G,W]of z.modelPanels)if(W.sourceId===J&&(z!==$||G!==Z))z.modelPanels.delete(G);return{...await BY($,J,Z),message:Q==="add"?"模型已显示":Q==="delete"?"补录模型已删除":"模型已隐藏"}}catch(H){return{ok:!1,message:`模型列表更新失败:${N(H)}`}}}async function YW($,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:QZ($.sessionName,Q.display,V)}}async function QW($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),V=$.tokenSource(Y.sourceId),X=async(_)=>{if(!Y.cardMessageId)return!1;let L="",j=!1,q=!1;try{if(L=await L$(Y.cardMessageId),X$(L,1),j=await A0(L,T.modelPanel,_,{notifyCardFailure:!1}),!j)throw Error("model panel replace rejected");if(q=await R0(L,{config:{streaming_mode:!1}}),!q)throw Error("model panel streaming-off rejected")}catch(F){B(`model-custom: card update MISS (${F?.message??F})`)}finally{if(L){if(!q)try{q=await R0(L,{config:{streaming_mode:!1}})}catch(F){B(`model-custom: streaming-off retry MISS (${F?.message??F})`)}if(j&&q)try{await H$(L)}catch(F){B(`model-custom: card dispose MISS (${F?.message??F})`)}else B(`model-custom: retain card state after checked MISS mutation=${j} streamingOff=${q} card=${L.slice(0,12)}`)}}return j&&q},H=async(_,L)=>{if(await X(_))return!0;let q=`⚠️ 模型补录结果未能写回原卡。${L}
239
- 请重新发送 model 打开面板。`;if(!await w($.chatId,q))B(`model-custom: visible fallback send MISS (${L})`);return!1},z=(_)=>H(L9(!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 H(L9(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;try{await nG(V.id,Q,$.codexAccountId())}catch(_){return B(`model-custom: config/refresh MISS (${N(_)})`),await z(`配置写入或模型刷新失败:${N(_)}`),!0}B(`model-custom: ${V.id} 补录 ${Q} by ${J}(记录已持久化)`);for(let _ of q$.all)for(let[L,j]of _.modelPanels)if(j.sourceId===V.id&&(_!==$||L!==Y.panelId))_.modelPanels.delete(L);let G=$.tokenSource(V.id);if(!G||G.modelCatalogState?.status!=="ready")return await z(G?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let W=KY($,G),K=W.find((_)=>_.model===Q);if(!K)return await z("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Y.panelId,{models:W,messageId:Y.cardMessageId}),K.unavailableReason||!K.efforts.length)return await H(L9(!0,Q,`**MISS**:${K.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Q} 已补录,能力尚未确认。`),!0;if(K.efforts.length===1){let _=await $.onModelEffortSelect(K.model,K.efforts[0].effort,Y.panelId,J,K.provider),L=(j)=>H(j.pending?j9(!0,j.message):j.ok?O8({sessionName:$.sessionName,provider:K.provider,model:K.model,effort:K.efforts[0].effort,scope:_Y($,K.provider??"codex")}):j9(!1,j.message),j.message);if(await L(_),_.completion)_.completion.then(L).catch(async(j)=>{let q=`模型补录后的切换结果呈现失败:${N(j)}`;B(`model-custom: ${q}`),await w($.chatId,`❌ ${q}`)});return!0}return await H(A8({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:K}),`✅ 模型 ${Q} 已补录成功。`),!0}async function VW($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:U8($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:U8($.sessionName)}}function LU($,Z){return M$(Z?.provider)?Z.provider:F2($)}function _Y($,Z){if(Z==="codex"&&$.proc?.isAlive()&&$.proc.provider===Z)return"Codex 需重启进程生效(发 restart)。";if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${s0(Z)} 时使用。`}async function XW($,Z,J="",Y="",Q=null){let V=Z.trim();if(!V)return await E($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=LU(V,Q),H=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===X);if(!H)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(H.unavailableReason)return{ok:!1,message:H.unavailableReason};if(H.enabled===!1)return{ok:!1,message:`${H.displayName} 未配置,请先点「启用」`};if(H.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(H.efforts.length===1)return jY($,V,H.efforts[0].effort,J,Y,X);return{ok:!0,message:"",card:YZ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:H})}}async function jY($,Z,J,Y="",Q="",V=""){if($.modelSettingsChangesClosed)return{ok:!1,message:"daemon 正在停止,本次模型选择未执行"};if($.modelSettingsChange?.proc===$.proc&&$.modelSettingsChange?.phase==="pending")return{ok:!1,message:"上一项模型设置仍在等待后端确认,本次选择未执行;请等待结果,取消切换请发 kill 或 restart。"};let X=Z.trim(),H=J.trim();if(!X)return{ok:!1,message:"模型为空"};let z=Y.trim(),G=$.modelPanels.get(z),W=M$(V)?V:G?.models.find((x)=>x.model===X)?.provider??F2(X);if(W==="dsh"){if(!_0(H))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(W==="claude"){if(!F0(H))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!t0(H))return{ok:!1,message:"Codex reasoning effort 无效"};let K=H,_=G?.models.find((x)=>x.model===X&&(x.provider??"codex")===W);if(!_||!_.efforts.some((x)=>x.effort===K))return{ok:!1,message:`${s0(W)} · ${X}/${K} 不在选项中`};let L=$.tokenSource(_.sourceId);if(L?.modelCatalogState){if(!L.enabled||L.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${L.modelCatalogState.error??L.modelCatalogState.status}`};if(!L.models.some((x)=>x.model===X&&x.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let j=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,q=!$.processSourceMatches(L,X)||!!L?.modelEnvironmentRevision&&L.modelEnvironmentRevision($.currentModelLabel()??"")!==L.modelEnvironmentRevision(X),F=$.modelSelectionNeedsProcessStop(W,_.sourceId??$.selectedTokenSourceId,X);if($.currentProvider()===W&&!j&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!F&&!q)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${s0(W)} · ${X} / ${K}`,card:_9({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==W&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${s0(W)}`};let U=$.currentModelLabel()!==X||j,A=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((q||F)&&$.proc?.isAlive()&&A)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(W==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&U&&A)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===W&&!j&&!q&&!F){let S=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(X)??X:X;if(W==="codex")await $.proc.setModelSettings(S,K);else return await _U($,$.proc,X,S,K,z,_.sourceId)}await $.applyModelSelectionUnlocked(W,X,K,_.sourceId);let x=_Y($,W);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${s0(W)} · ${X} / ${K}`,card:_9({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:x})}}catch(x){let S=`模型切换失败: ${N(x)}`;return B(`session "${$.sessionName}": set model settings failed: ${N(x)}`),{ok:!1,message:S}}}var GY=20;var HW=O(()=>{j0();LY();Z0();zY();U1();j0();Q$();f$();r();f()});import{createHash as qU}from"node:crypto";function DU($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function i9($="default"){return BW(KW($))}function WW($="default"){return MU(KW($))}function KW($){return $$().map((Z)=>Z.forAccount?.($)??Z)}async function MU($){let Z=BW($),Y=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((z)=>z.tokenSourceId===V.id);if(X)return X;let H=await UU(V);return H===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:H}}))).filter((V)=>V!==null),Q=new Set(Y.map((V)=>V.tokenSourceId));return _W(Z.identities.filter((V)=>!Q.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Q.has(V.tokenSourceId)),...Y])}function UU($){let Z=zW.get($);if(Z&&(Z.expiresAt===null||Date.now()<Z.expiresAt))return Z.result;let J={expiresAt:null,result:AU($).finally(()=>{J.expiresAt=Date.now()+FU})};return zW.set($,J),J.result}async function AU($){let Z;try{let J=await $.readUsage();if(J.state==="ok")return null;Z=J.reason??`订阅可用性查询失败:${J.state}`}catch(J){Z=J instanceof Error?J.message:String(J)}return B(`agent identities ${$.id} MISS: ${Z}`),Z}function BW($){let Z=[],J=[];for(let Y of $)OU(Y,Z,J);return _W(Z,J)}function _W($,Z){return{catalogGeneration:qU("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function OU($,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(NU($,Q,Y))}function NU($,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:DU($.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:GW($.defaultModel)===GW(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function GW($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var FU=1800000,zW;var A7=O(()=>{f();Z0();zW=new WeakMap});import{randomUUID as RU}from"node:crypto";async function jW($,Z){if(!Z.trim()){await w($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}qW(),await y2();let J=`agents_${RU()}`;if(n9.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,PW(J)))await w($.chatId,"❌ agents 面板发送失败")}function LW($,Z,J){let Y=xU($,J),Q=Number(Z);if(!Number.isInteger(Q))return SU("无效页码");let V=EU(Y.codexAccountId);return Y.page=Math.max(0,Math.min(V-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:PW($)}}function PW($){let Z=n9.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=i9(Z.codexAccountId),Y=Math.max(1,Math.ceil(J.identities.length/O7));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*O7;return qZ({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+O7),failures:J.sourceFailures})}function EU($){return Math.max(1,Math.ceil(i9($).identities.length/O7))}function xU($,Z){qW();let J=n9.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function SU($){return{ok:!1,message:$,card:Q1({title:"agents",message:$,ok:!1})}}function qW(){let $=Date.now()-TU;for(let[Z,J]of n9)if(J.createdAt<$)n9.delete(Z)}var O7=8,TU=1800000,n9;var FW=O(()=>{Q$();r();A7();Z0();n9=new Map});var FY={};S$(FY,{withTasklistLifecycleLock:()=>E7,tasklistNameForProject:()=>T7,reconcileTasklistDeletions:()=>yU,isTasklistAlreadyDeletedError:()=>DW,getTasklistBinding:()=>g$,enableTasklist:()=>PY,deleteTasklistRemoteIdempotently:()=>MW,deleteTasklist:()=>qY});import{existsSync as bU,readFileSync as kU}from"node:fs";function T7($){return`${$}[lodestar]`}function g$($){let Z=I$.get($);return Z?j4(Z):null}async function E7($,Z){let J=N7.get($)??Promise.resolve(),Y,Q=new Promise((X)=>{Y=X}),V=J.catch(()=>{}).then(()=>Q);N7.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Y(),N7.get($)===V)N7.delete($)}}function DW($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function MW($,Z=hZ){try{return await Z($),"deleted"}catch(J){if(DW(J))return"already_deleted";throw J}}async function PY($,Z){return await E7($,async()=>{let J=g$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=T7($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await vZ(Z),V=await fZ(Y,Q),X={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Q,createdAt:V.createdAt};return R7($,X),j4(X)})}async function qY($,Z){return await E7($,async()=>{let J=g$($);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},R7($,J);return await UW($,Z)})}async function UW($,Z){let J=g$($);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,R7($,J);try{if(await MW(Z)==="already_deleted")B(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(I$);return Q.delete($),AW(Q),I$.delete($),j4(J)}catch(Y){let Q=g$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),R7($,Q);throw Y}}async function yU(){let $=[...I$.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await E7(J.projectName,()=>UW(J.projectName,J.guid)),B(`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 wU(){if(!bU(J3))return;try{let $=JSON.parse(kU(J3,"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:vU(Y.deleting)};I$.set(Z,Q)}B(`tasklist: loaded ${I$.size} project bindings`)}catch($){B(`tasklist: load map failed: ${$}`)}}function vU($){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 R7($,Z){let J=new Map(I$);J.set($,j4(Z)),AW(J),I$.set($,j4(Z))}function AW($=I$){let Z={};for(let[J,Y]of $)Z[J]=j4(Y);o(J3,Z)}function j4($){return JSON.parse(JSON.stringify($))}var I$,N7;var DY=O(()=>{Q0();r();f();x0();I$=new Map,N7=new Map;wU()});function K1($,Z,J=!1){let Y=$.worktreeProjectName();return LZ({projectName:Y,tasklistName:T7(Y),binding:g$(Y),notice:Z,confirmDelete:J})}async function OW($){if(!await u($.chatId,K1($)))await w($.chatId,"❌ task 面板发送失败")}async function NW($){let Z=$.worktreeProjectName();try{let J=g$(Z),Y=await PY(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:K1($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${N(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${N(J)}`),{ok:!1,message:Y,card:K1($,{type:"error",content:`❌ ${Y}`})}}}function RW($,Z){let J=$.worktreeProjectName(),Y=g$(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 TW($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let V=`已删除 ${(await qY(J,Y)).name}`;return{ok:!0,message:V,card:K1($,{type:"success",content:`✅ ${V}`})}}catch(Q){let V=`删除失败: ${N(Q)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${N(Q)}`),{ok:!1,message:V,card:K1($,{type:"error",content:`❌ ${V}`})}}}var EW=O(()=>{Q$();r();f();DY()});import{open as hU}from"node:fs/promises";import{basename as IU}from"node:path";function MY($){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 m$($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class xW{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:z0,getToken:E$,retry:f1,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 X=await this.deps.getToken(),H=Y?.(),z=H instanceof FormData,G=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(G>0)await this.deps.wait(G);Q?.throwIfAborted(),this.lastStartedAt=Date.now();let W=AbortSignal.timeout(pU),K=new AbortController,_=()=>K.abort(W.reason),L=()=>K.abort(Q.reason);W.addEventListener("abort",_,{once:!0}),Q?.addEventListener("abort",L,{once:!0});let j=K.signal;try{let q=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!z&&H!==void 0?{"Content-Type":"application/json"}:{}},...H!==void 0?{body:z?H:JSON.stringify(H)}:{},signal:j});return(await p2(q,$)).data}catch(q){if(j.aborted&&j.reason?.name==="TimeoutError")throw j.reason;throw q}finally{W.removeEventListener("abort",_),Q?.removeEventListener("abort",L)}}));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:m$(J?.token,"交付文件夹"),url:MY(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return m$(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Y=m$(J?.token,"群文件夹");if(Y!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Y,url:MY($.url),name:m$(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 R$&&Q.code===99991672)throw new R$("同步群文件夹名称需要应用身份权限 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){m$(Z,"交付群"),m$(J,"交付发起人");let Q=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let X 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",()=>X,Y);let V=await this.request("核对交付文件夹权限",Q,"GET",void 0,Y);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[X,H,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((W)=>W.member_type===X&&W.member_id===H)?.perm!==z)throw Error(`交付文件夹权限未生效:${X} / ${z}`)}async closeFileLinkSharing($,Z){m$($,"交付文件");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 hU($,"r");try{let V=await Q.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=IU($),H={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=gU){let j=await Q.readFile(),q=await Q.stat();if(j.length!==V.size||q.mtimeMs!==V.mtimeMs||q.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let F=new FormData;for(let[R,D]of Object.entries(H))F.append(R,String(D));return F.append("file",new Blob([Uint8Array.from(j)]),X),F},Y)}else{let j=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>H,Y),q=m$(j?.upload_id,"分片上传事务"),F=j?.block_size,R=j?.block_num;if(!Number.isSafeInteger(F)||F<=0||F>mU||!Number.isSafeInteger(R)||R!==Math.ceil(V.size/F))throw Error("云空间返回的分片策略无效");for(let U=0;U<R;U++){Y?.throwIfAborted();let A=Math.min(F,V.size-U*F),x=Buffer.alloc(A),S=0;while(S<A){let h=await Q.read(x,S,A-S,U*F+S);if(!h.bytesRead)throw Error("交付文件在分片读取时发生变化");S+=h.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let h=new FormData;return h.append("upload_id",q),h.append("seq",String(U)),h.append("size",String(A)),h.append("file",new Blob([Uint8Array.from(x)]),X),h},Y)}let D=await Q.stat();if(D.size!==V.size||D.mtimeMs!==V.mtimeMs||D.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:q,block_num:R}),Y)}let G=m$(z?.file_token,"已上传文件"),W={token:G,url:"",name:X,bytes:V.size};J(W),await this.closeFileLinkSharing(G,Y);let K=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:G,doc_type:"file"}],with_url:!0}),Y),_=K?.metas?.find((j)=>j.doc_token===G&&j.doc_type==="file");if(K?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let L={...W,url:MY(_.url)};return J(L),L}finally{await Q.close()}}}var gU=20971520,mU=20971520,pU=60000,$2;var SW=O(()=>{o0();r();S8();$2=new xW});import{randomUUID as CW}from"node:crypto";import{basename as cU}from"node:path";class UY{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:CW(),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:CW(),path:$,name:cU($),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}
240
- ${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?`
241
- 已上传文件所在文件夹:${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 bW=()=>{};class AY{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=T$(Z),Y=this.load(),Q=Y.workspaces[J]?.enabled;if(Q===void 0){let X=new Set(this.legacyChats($,J).map((H)=>Y.groups[H].legacyEnabled));if(X.size>1)throw Error("同一工作目录的旧群文件交付设置冲突,请发送 files on 或 files off 统一设置");if(X.size)Q=X.values().next().value,this.commitMode($,J,Q)}let V=this.load().groups[$]?.folder;return{enabled:Q??!1,...V?{folder:structuredClone(V)}:{}}}mode($,Z){return this.get($,Z).enabled?"drive":"chat"}enable($,Z,J){let Y=T$(Z);return this.exclusive(`workspace:${Y}`,()=>this.exclusive(`chat:${$}`,async()=>{return await this.prepare($,J,!0),this.commitMode($,Y,!0),this.get($,Z)}))}disable($,Z){let J=T$(Z);return this.exclusive(`workspace:${J}`,async()=>{return this.commitMode($,J,!1),this.get($,Z)})}resolveFolder($,Z){return this.exclusive(`chat:${$.chatId}`,()=>this.prepare($.chatId,$.managerOpenId,!0,Z))}bindExisting($,Z,J,Y){return this.exclusive(`chat:${$}`,async()=>{let Q=this.load().groups[$];if(Q?.folder&&Q.folder.token!==Y.token)throw Error("本群已经绑定其他文件夹");let V=await this.deps.getFolder(Y);return this.commitFolder($,V),await this.prepare($,J,!1),this.get($,Z)})}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.load().groups[$]?.folder;if(!V){if(!J)throw Error("本群尚未绑定云空间文件夹");V={...await this.deps.createFolder(Q,Y),name:Q},this.commitFolder($,V)}let X=await this.deps.getFolder(V,Y);if(X.token!==V.token)throw Error("云空间返回的文件夹与本群绑定不一致");if(V=X.name===Q?X:await this.deps.renameFolder(X,Q,Y),V.name!==Q)throw Error("文件夹名称尚未与群名同步");return this.commitFolder($,V),await this.deps.grantFolderAccess(V,$,Z,Y),V}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.state)return this.state;let $=this.deps.read();if($===void 0)return this.state={version:2,workspaces:{},groups:{}};let Z=JSON.parse($);if(![1,2].includes(Z?.version)||!a9(Z.groups)||Z.version===2&&!a9(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Y,Q]of Object.entries(Z.workspaces??{})){if(!a9(Q)||typeof Q.enabled!=="boolean"||T$(Y)!==Y)throw Error("工作目录文件交付开关无效");J.workspaces[Y]={enabled:Q.enabled}}for(let[Y,Q]of Object.entries(Z.groups)){if(!Y||!a9(Q))throw Error("群文件夹绑定无效");let V=Z.version===1?Q.enabled:Q.legacyEnabled;if((Z.version===1||V!==void 0)&&typeof V!=="boolean")throw Error("群文件交付开关无效");if(V&&!Q.folder)throw Error("已启用的旧群缺少文件夹绑定");if(Q.folder!==void 0)uU(Q.folder);J.groups[Y]={...Q.folder?{folder:structuredClone(Q.folder)}:{},...V===void 0?{}:{legacyEnabled:V}}}return this.state=J}legacyChats($,Z){return Object.entries(this.load().groups).filter(([J,Y])=>{if(Y.legacyEnabled===void 0)return!1;if(J===$)return!0;let Q=this.deps.workDirForChat(J);return Q!==void 0&&T$(Q)===Z}).map(([J])=>J)}commitMode($,Z,J){let Y=structuredClone(this.load());Y.workspaces[Z]={enabled:J};for(let Q of this.legacyChats($,Z))delete Y.groups[Q].legacyEnabled;this.commit(Y)}commitFolder($,Z){let J=structuredClone(this.load());J.groups[$]={...J.groups[$],folder:Z},this.commit(J)}commit($){this.deps.write($),this.state=$}}function a9($){return!!$&&typeof $==="object"&&!Array.isArray($)}function uU($){if(!a9($)||typeof $.token!=="string"||!$.token.trim()||typeof $.name!=="string"||!$.name.trim()||typeof $.url!=="string")throw Error("群文件夹绑定无效");let Z=new URL($.url);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("群文件夹链接无效")}var kW=O(()=>{w8()});import{join as lU}from"node:path";import{readFileSync as dU}from"node:fs";function yW($){return new UY($,{resolveFolder:(Z,J)=>L4.resolveFolder(Z,J),uploadFile:(Z,J,Y,Q)=>$2.uploadFile(Z,J,Y,Q),sendCard:(Z)=>u($.chatId,x6(Z)),persist:(Z)=>o(lU(QQ,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await E($.chatId,Z))throw Error(Z)}})}var L4;var wW=O(()=>{r();SW();bW();s3();Q0();x0();f();kW();w8();L4=new AY({read:()=>{try{return dU(J5,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>o(J5,$),workDirForChat:($)=>{let Z=[...G0].filter(([,Q])=>Q===$).map(([Q])=>Q),J=W0.get($);if(!Z.length&&J)Z.push(J);let Y=new Set(Z.map((Q)=>T$(n2(Q))));if(Y.size>1)throw Error(`旧文件交付群绑定了多个工作目录: ${$}`);return Y.values().next().value},getChatName:($,Z)=>$2.getChatName($,Z),createFolder:($,Z)=>$2.createFolder($,Z),getFolder:($,Z)=>$2.getFolder($,Z),renameFolder:($,Z,J)=>$2.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Y)=>$2.grantFolderAccess($,Z,J,Y)})});async function vW($,Z,J,Y,Q,V){let X,H="",z="";try{switch(Y.trim().toLowerCase()){case"":case"status":X=Q.get($);break;case"on":X=await Q.enable($,J),H="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Q.disable($),H="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(W){z=W instanceof Error?W.message:String(W);try{X=Q.get($)}catch{X=void 0}}let G=S6({groupName:Z,workDir:V,settings:X,notice:H,error:z});if(!await Q.sendCard(G))await Q.reportError(`❌ 文件交付设置卡发送失败${z?`:${z}`:""}`)}var fW=O(()=>{s3()});function hW($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
242
- `)}function IW($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",hW(Z),"- 文件交付约定由 Lodestar 按工作目录设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写工作目录配置。"}`,J[$],...iU].join(`
243
- `)}function gW($){return`[Lodestar 文件交付约定更新]
234
+ `)}function e9($){let Z=WG.then($);return WG=Z.then(()=>{},()=>{}),Z}async function $3($,Z,J){EM($,Z),J?.(),jV(),DQ(),await V9()}function GG($,Z){return e9(()=>$3($,Z))}function KG($,Z,J=$.setup){return e9(async()=>{let Q=!1;try{if(!$.configSectionId||!J)throw Error("此来源不支持配置命令");let Y=u4().token_sources,V={...Y,...hJ(Y,$.configSectionId,Z)};await J.validate(u9(V)[$.configSectionId]),await $3($.configSectionId,Z,()=>{Q=!0})}catch(Y){throw new S5(Y,Q)}})}function BG($,Z,J,Q="default"){return e9(async()=>{let Y=H0($,Q);if(!Y?.enabled||!Y.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Y.modelSelection.modelIds.filter((_)=>Y.models.find((L)=>L.model===_)?.origin!=="custom");if(J==="add"){if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");let _=Y.modelSelection.availableModels.find((L)=>L.model===Z);if(_?.origin==="custom")throw Error("补录模型请使用删除操作");if(!_||Y.modelSelection.mode!=="catalog"&&(_.unavailableReason||!_.efforts.length))throw Error("模型不在允许添加的账号目录中");if(V.includes(Z))throw Error("模型已在可选列表中")}else if(!V.includes(Z))throw Error("模型已不在可选列表中");let X=J==="add"?[...V,Z]:V.filter((_)=>_!==Z),H=g.token_sources[$],z=Y.modelSelection.mode==="catalog",W=Q0(H?.hidden_models),G=z?{hidden_models:(J==="remove"?[...new Set([...W,Z])]:W.filter((_)=>_!==Z)).join(",")}:{models:X.join(",")};await $3($,G);let K=H0($,Q);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function _G($,Z,J="default"){return e9(async()=>{let Q=Z.trim();if(!Q||Q.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Q))throw Error("模型 ID 无效,请只填写一个完整模型名");let Y=H0($,J);if(!Y?.enabled)throw Error("账号不可用");if(Y.validateCustomModelId?.(Q),(Y.modelSelection?.availableModels??Y.models).some((z)=>z.model.toLowerCase()===Q.toLowerCase()))throw Error("模型已在目录或补录记录中;隐藏项请使用“显示”");if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");if(Y.verifyModel){let z=await Y.verifyModel(Q);if(z!=="exists")throw Error(z==="not_found"?"端点确认不存在":"无法校验模型:端点无响应或凭据问题")}let X=g.token_sources[$];await $3($,{custom_models:[...Q0(X?.custom_models),Q].join(",")});let H=H0($,J);if(H?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${H?.modelCatalogState?.error??"MISS"}`)})}function jG($,Z,J="default"){return e9(async()=>{let Q=H0($,J),Y=Q?.modelSelection?.availableModels.find((W)=>W.model===Z);if(!Q?.enabled||Y?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=g.token_sources[$]??{},X=(W)=>W?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),H={custom_models:Q0(V.custom_models).filter((W)=>!X(W)).join(","),hidden_models:Q0(V.hidden_models).filter((W)=>!X(W)).join(","),...V.models!==void 0?{models:Q0(V.models).filter((W)=>!X(W)).join(",")}:{},...X(V.model)?{model:"",effort:""}:{},...V.slots?{slots:V.slots.split(",").filter((W)=>!X(W.slice(W.indexOf("=")+1))).join(",")}:{}};await $3($,H);let z=H0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}var WG,S5;var MQ=O(()=>{V0();S0();UQ();e();x0();U1();l9();WG=Promise.resolve();S5=class S5 extends Error{saved;constructor($,Z){super($ instanceof Error?$.message:String($),{cause:$});this.saved=Z}}});var C5={};v$(C5,{runTokenSourceSetup:()=>bM,runClaudeSubscriptionCommand:()=>SM,onTokenSourceEnable:()=>CM});async function SM($,Z){if(Z&&Z!=="on"&&Z!=="off"){await S($.chatId,`用法:${"claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"}`);return}if(Z)try{await GG("claude-sub",{enabled:Z==="on"})}catch(H){let z=H instanceof Error?H.message:String(H);B(`claude-sub ${Z} failed: ${z}`),await S($.chatId,`❌ Claude Code 订阅开关更新失败:${z}`);return}let Q=I0("claude-sub"),Y=g.token_sources["claude-sub"]?.enabled!==!1,V=Q?.modelCatalogState,X=[`Claude Code 订阅:${Y?"已启用":"已禁用"}(Lodestar 全局)`];if(Y&&(!Q?.enabled||V?.status!=="ready"))X.push(`可用性 MISS:${V?.error??(V?.status==="loading"||V?.status==="idle"?"模型目录尚未就绪,请发送 md 刷新":"订阅来源不可用")}`);if(X.push("所有群共用;保留本机登录态。"),!Y)X.push("禁止新任务,已在执行的任务继续完成。");X.push("claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"),await S($.chatId,X.join(`
235
+ `))}async function CM($,Z){let J=I0(Z);if(!J){await S($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled&&J.modelCatalogState?.status!=="failed"){await S($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Q=k1().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup){let Y=J.modelCatalogState?.status==="failed"?`${J.display} 当前不可用:${w0(J.modelCatalogState.error??"MISS")}
236
+ `:"";await S($.chatId,Y+Q.setup.hint(J.display))}else if(J.kind==="codex-subscription"){if(!await u($.chatId,P$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await S($.chatId,g.token_sources["claude-sub"]?.enabled===!1?"Claude Code 订阅已在 Lodestar 中禁用。发送 `claude-sub on` 启用,所有群共用,本机登录态保持不变。":J.modelCatalogState?.error??"请在运行 Lodestar 的本机执行 `claude auth login` 登录 Claude 订阅,完成后发送 `md` 刷新。");else if(J.kind==="claude-native")await S($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function bM($,Z,J){let Q=k1().find((z)=>z.setup?.commandSuffix===Z||z.usageSetup?.commandSuffix===Z),Y=Q?.usageSetup?.commandSuffix===Z,V=Y?Q?.usageSetup:Q?.setup;if(!Q||!V||!Q.configSectionId){await S($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let X=V.parseArgs(J);if("error"in X){await S($.chatId,X.error);return}let H=!1;try{await KG(Q,X.config,V),H=!0;let z=I0(Q.configSectionId),W=mz(Q.configSectionId).map((_)=>I0(_)),G=W.find((_)=>(!Y||_?.enabled)&&_?.modelCatalogState?.status!=="ready");if(Y){let _=G?`
237
+ 模型目录仍为 MISS:${w0(G.modelCatalogState?.error??"尚未就绪",[X.config.management_token])}`:"";await S($.chatId,`✅ ${z?.display??Z} 真实余额校验通过,配置已保存。发送 hi 查看;回复页脚使用同一账户余额。${_}`);return}if(G||W.some((_)=>!_)){let _=w0(G?.modelCatalogState?.error??"模型目录尚未就绪",[X.config.api_key,X.config.auth_token]);await S($.chatId,`❌ ${z?.display??Z} 凭据校验通过、配置已保存,但暂不可用:${_}
238
+ 处理后发送 md 刷新。`);return}let K=[...new Set(W.filter((_)=>!!_).map((_)=>y0(_.agent)))];await S($.chatId,`✅ ${z.display} 校验通过,配置已保存。${K.length>1?`${K.join(" 和 ")} 共用该账号。`:""}发送 md 选择模型。`)}catch(z){let W=H||z instanceof S5&&z.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",G=w0(z,[X.config.api_key,X.config.auth_token,X.config.management_token]);await S($.chatId,`❌ ${W}:${G}`)}}var b5=O(()=>{r();e();MQ();H4();S0();h();l9();G0()});async function LG($,Z,J="",Q){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (O5(),XQ));return await K($,Y[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:K}=await Promise.resolve().then(() => (O5(),XQ));return await K($,V[1].toLowerCase(),(V[2]??"").trim(),J,Q),!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (b5(),C5));return await K($,(X[1]??"").trim().toLowerCase()),!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 z=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(z)return await $.runFileDeliveryCommand((z[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let W=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(W){let{runTokenSourceSetup:K}=await Promise.resolve().then(() => (b5(),C5));return await K($,W[1].trim().toLowerCase(),(W[2]??"").trim()),!0}let G=kM.get(Z.trim().toLowerCase());if(!G)return!1;switch(G){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let K=!$.isRunning(),_=$.backendLabel(),L=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${_}`)):null,j=$.withModel(`\uD83D\uDE80 启动 ${_}`);if(!(K?await $.start({announce:!L,onStatus:(P)=>{j=P,$.setStatusCard(L,P)}}):!0))return await $.closeStatusCard(L,j.startsWith("❌")?j:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(L)await $.closeStatusCard(L,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:N}=await Promise.resolve().then(() => (H4(),kz));if(!await u($.chatId,N({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"})))throw Error("额度等待卡片发送失败")}return!0}if(L)return await $.replaceStatusCardWithConsole(L,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(L,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let L=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!L,onStatus:(j)=>$.setStatusCard(L,j)}),await $.closeStatusCard(L,"\uD83D\uDED1 已取消额度恢复")}catch(j){throw await $.closeStatusCard(L,`❌ ${R(j)}`),j}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(K)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await S($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let L=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(L)await $.closeStatusCard(L,"⚪ 无正在执行的 turn");else await S($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let _=new Set;for(let[L,j]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(j)k0(L,j);t0(L,"CrossMark"),_.add(L)}for(let L of $.pendingMidTurnMsgs)if(L.msgId&&!_.has(L.msgId))t0(L.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 K=$.isRunning(),_=$.backendLabel($.proc?.provider??$.currentProvider()),L=K?`\uD83D\uDED1 停止 ${_}`:"⚪ session 当前未运行",j=await $.openStatusCard("kill",L,K?"red":"grey"),q=null,P=K?`✅ ${_} 已终止`:`⚪ ${_} 未运行`;try{await $.stop("已终止",{announce:!j,onStatus:(N)=>{$.setStatusCard(j,N)}})}catch(N){q=N,P=$.isRunning()?`❌ ${_} 未确认终止: ${R(N)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${_} 停止收尾失败: ${R(N)}`}finally{try{await $.closeStatusCard(j,P)}catch(N){B(`session "${$.sessionName}": kill status card close failed: ${R(N)}`),await I($.chatId,`${P}
239
+ ⚠️ kill 状态卡片终态写入失败: ${R(N)}`)}}if(q&&!j)await I($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?O0($.lastSessionId):"",_=$.backendLabel($.proc?.provider??$.currentProvider()),L=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${_}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${_}`),j=await $.openStatusCard("restart",L),q=L,P=await $.restart(!0,{announce:!j,onStatus:(D)=>{q=D,$.setStatusCard(j,D)}}),N=P?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(j,P?$.withModel(N):N)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let K=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(K)await $.closeStatusCard(K,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await S($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let K=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),_="\uD83E\uDDF9 清空并启动新会话",L=await $.restart(!1,{announce:!K,onStatus:(j)=>{_=j,$.setStatusCard(K,j)}});await $.closeStatusCard(K,L?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):_.startsWith("❌")?_:"❌ 清空失败")}return!0}}var kM;var qG=O(()=>{r();h();kM=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 vM($){let Z=!1,J=()=>{},Q=()=>{},Y=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",W),$.off("error",G)},X=(_)=>{if(Z)return;Z=!0,V(),J(_)},H=(_)=>{if(Z)return;Z=!0,V(),Q(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Y&&_.threadId!==Y)return;X(_)},W=()=>H(Error(`${$.provider} process exited before context compaction completed`)),G=(_)=>H(_ instanceof Error?_:Error(String(_))),K=new Promise((_,L)=>{J=_,Q=L});return $.on("context_compacted",z),$.once("exit",W),$.once("error",G),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function fM($,Z){let J=[],Q=new Set,Y=(H,z)=>{let W=z.threadId??Z;if(W&&H.threadId&&H.threadId!==W)return!1;if(z.turnId)return H.turnId===z.turnId;return!0},V=(H)=>{for(let z=J.length-1;z>=0;z--){let W=J[z];if(W&&Y(W,H))return W}return null},X=(H)=>{if(Z&&H.threadId&&H.threadId!==Z)return;let z={usage:H.usage,contextWindow:H.contextWindow,threadId:H.threadId,turnId:H.turnId};J.push(z);for(let W of[...Q])if(Y(z,W.notice))W.finish(z)};return $.on("token_usage",X),{waitFor(H,z){let W=V(H);if(W)return Promise.resolve(W);return new Promise((G)=>{let K=null,_={notice:H,finish:(L)=>{if(K)clearTimeout(K);Q.delete(_),G(L)}};K=setTimeout(()=>_.finish(null),z),Q.add(_)})},cancel(){$.off("token_usage",X);for(let H of[...Q])H.finish(null)}}}function hM($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=X8($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=H8($.contextWindow);return` · \uD83E\uDDE0 ${RX(Z,J)} (${z8(Z,J)})`}async function FG($){$.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 S($.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 S($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let W=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(W)await $.closeStatusCard(W,"⏳ 上下文压缩已在进行中");else await S($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Q=J.sessionId?O0(J.sessionId):"",Y=$.withModel(Q?`\uD83E\uDDE0 压缩上下文 thread=${Q}`:"\uD83E\uDDE0 压缩上下文…"),V=await $.openStatusCard("compact",Y,"orange"),X=async(W)=>{if(V)await $.closeStatusCard(V,W);else await S($.chatId,W)},H=vM(J),z=fM(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let W=await H.promise,G=await z.waitFor(W,yM),K=W.threadId?` thread=${O0(W.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${hM(G)}`))}catch(W){if(H.cancel(),W instanceof S1)await X($.withModel(`ⓘ ${W.message}`));else await X(`❌ 上下文压缩失败: ${R(W)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var yM=1500;var PG=O(()=>{G0();r()});import{randomUUID as gM}from"node:crypto";function DG($,Z){return{ok:!1,message:Z,card:S8($.sessionName,!1,Z)}}async function OQ($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return DG($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${R(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof T2&&J.error.confirmedModel!==null?Z.model:null,Z.confirmedEffort=J.ok?Z.effort:null;let Q=J.ok?null:R(J.error);if(J.ok)try{if($.modelSelectionNeedsProcessStop(Z.provider,Z.sourceId??$.selectedTokenSourceId,Z.model,Z.effort))throw Error("等待期间进程账号配置已变化,请 stop 后重新选择");await $.applyModelSelectionUnlocked(Z.provider,Z.model,Z.effort,Z.sourceId)}catch(Y){Q=`模型和思考档位已应用,但保存选择失败:${R(Y)}`}if(Q!==null)return Z.phase="failed",Z.error=`${Q}。本次完整设置未保存,后续输入暂停;请重新发送 md 完成选择,或 restart 恢复已保存的设置。`,B(`session "${$.sessionName}": model settings incomplete: ${Z.error}`),DG($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${y0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:U9({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:TQ($,Z.provider)})}}async function mM($,Z,J,Q,Y,V,X){let H,z=new Promise((j)=>{H=j}),W={proc:Z,provider:Z.provider,model:J,effort:Y,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(j){W.cancelled=j,H({ok:!1,error:Error(j)})}};$.modelSettingsChange=W;let G=Promise.resolve().then(()=>Z.setModelSettings(Q,Y)).then(()=>({ok:!0}),(j)=>({ok:!1,error:j})),K=Promise.race([G,z]),_=Symbol("model-settings-pending"),L;try{let j=await Promise.race([K,new Promise((P)=>{L=setTimeout(()=>P(_),20000)})]);if(j!==_)return await OQ($,W,j);let q=`正在等待 ${y0(Z.provider)} 确认 ${J} / ${Y},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:q,card:S8($.sessionName,!0,q),completion:K.then((P)=>$.finishModelSettingsChange(W,P))}}finally{clearTimeout(L)}}function pM($){let Z=$.currentTokenSource();return J$().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 NQ($,Z,J=Z.models){let Q=$.currentModelLabel(),Y=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let H=V&&Q===X.model;return{provider:Z.agent,sourceId:Z.id,model:X.model,displayName:X.display,description:X.unavailableReason??(X.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:X.unavailableReason,origin:X.origin,enabled:!0,isDefault:!1,selected:H,efforts:X.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===X.defaultEffort,selected:H&&Y===z}))}})}async function UG($){await V9();let Z=gM(),J=pM($);$.modelPanels.set(Z,{models:[]});let Q=await u($.chatId,GZ({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}));if(!Q)$.modelPanels.delete(Z),await I($.chatId,"❌ 模型面板发送失败");else{let Y=$.modelPanels.get(Z);if(Y)Y.messageId=Q}}async function RQ($,Z,J=""){let Q=Z.trim(),Y=$.tokenSource(Q);if(!Y)return{ok:!1,message:`未知账号: ${Q}`};if(!Y.enabled)return{ok:!1,message:Y.modelCatalogState?.error??`${Y.display} 未配置,请先点「启用」`};let V=J.trim();if(!$.modelPanels.has(V))return{ok:!1,message:"模型面板已失效,请重新发送 model"};if(Y.modelCatalogState?.status==="failed")return{ok:!1,message:`模型目录 MISS:${Y.modelCatalogState.error??"刷新失败"}`};let X=NQ($,Y),H=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Q,messageId:H,mode:"select",editable:!!Y.modelSelection,sourceRevision:Y.spawnRevision}),k5($,V,Q,0)}async function k5($,Z,J,Q){let Y=$.modelPanels.get(Z);if(!Y?.catalog||Y.sourceId!==J)return{ok:!1,message:"模型面板已失效,请重新发送 model"};let V=Math.max(1,Math.ceil(Y.catalog.length/AQ));if(!Number.isInteger(Q)||Q<0||Q>=V)return{ok:!1,message:"模型页码无效"};return Y.models=Y.catalog.slice(Q*AQ,(Q+1)*AQ),Y.page=Q,Y.totalPages=V,{ok:!0,message:"",card:KZ({sessionName:$.sessionName,panelId:Z,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:Y.models,sourceId:J,editable:Y.editable,allowCustom:!0,mode:Y.mode,...V>1?{pagination:{sourceId:J,page:Q,totalPages:V}}:{}})}}async function MG($,Z,J){let Q=$.modelPanels.get(Z),Y=$.tokenSource(J);if(!Q||Q.sourceId!==J||!Y?.enabled||!Y.modelSelection)return{ok:!1,message:"模型管理面板已失效,请重新发送 md"};if(Y.modelCatalogState?.status!=="ready")return{ok:!1,message:Y.modelCatalogState?.error??"目录未就绪"};let V=Y.modelSelection.availableModels.filter((X)=>X.origin!=="custom"&&!Y.modelSelection.modelIds.includes(X.model)&&(Y.modelSelection.mode==="catalog"||!X.unavailableReason&&X.efforts.length>0));return $.modelPanels.set(Z,{models:[],catalog:NQ($,Y,V),sourceId:J,messageId:Q.messageId,mode:"add",editable:!0,sourceRevision:Y.spawnRevision}),k5($,Z,J,0)}async function AG($,Z,J,Q,Y){let V=$.modelPanels.get(Z),X=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!X?.modelSelection||V.sourceRevision!==X.spawnRevision||V.mode!==(Y==="add"?"add":"select")||!V.models.some((H)=>H.model===Q))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Y==="delete"){let H=[...D$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Q.replace(/\[1m\]$/,""));if(H.length)return{ok:!1,message:`补录模型仍被会话 ${H.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Y==="delete")await jG(J,Q,$.codexAccountId());else await BG(J,Q,Y,$.codexAccountId());for(let z of D$.all)for(let[W,G]of z.modelPanels)if(G.sourceId===J&&(z!==$||W!==Z))z.modelPanels.delete(W);return{...await RQ($,J,Z),message:Y==="add"?"模型已显示":Y==="delete"?"补录模型已删除":"模型已隐藏"}}catch(H){return{ok:!1,message:`模型列表更新失败:${R(H)}`}}}async function OG($,Z,J,Q=""){let Y=$.tokenSource(Z.trim());if(!Y)return{ok:!1,message:`未知账号: ${Z}`};if(!Y.enabled)return{ok:!1,message:`${Y.display} 未配置`};let V=J.trim();if(!V)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Y.id,panelId:V,cardMessageId:Q},{ok:!0,message:"等待模型名",card:_Z($.sessionName,Y.display,V)}}async function NG($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),V=$.tokenSource(Q.sourceId),X=async(_)=>{if(!Q.cardMessageId)return!1;let L="",j=!1,q=!1;try{if(L=await F$(Q.cardMessageId),W$(L,1),j=await A0(L,E.modelPanel,_,{notifyCardFailure:!1}),!j)throw Error("model panel replace rejected");if(q=await R0(L,{config:{streaming_mode:!1}}),!q)throw Error("model panel streaming-off rejected")}catch(P){B(`model-custom: card update MISS (${P?.message??P})`)}finally{if(L){if(!q)try{q=await R0(L,{config:{streaming_mode:!1}})}catch(P){B(`model-custom: streaming-off retry MISS (${P?.message??P})`)}if(j&&q)try{await G$(L)}catch(P){B(`model-custom: card dispose MISS (${P?.message??P})`)}else B(`model-custom: retain card state after checked MISS mutation=${j} streamingOff=${q} card=${L.slice(0,12)}`)}}return j&&q},H=async(_,L)=>{if(await X(_))return!0;let q=`⚠️ 模型补录结果未能写回原卡。${L}
240
+ 请重新发送 model 打开面板。`;if(!await I($.chatId,q))B(`model-custom: visible fallback send MISS (${L})`);return!1},z=(_)=>H(A9(!1,Y,_),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${_}。`);if(!V||!V.enabled)return await z("账号不可用"),!0;if(!Y)return await z("模型名为空"),!0;if(V.models.some((_)=>_.model.toLowerCase()===Y.toLowerCase()))return await H(A9(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;try{await _G(V.id,Y,$.codexAccountId())}catch(_){return B(`model-custom: config/refresh MISS (${R(_)})`),await z(`配置写入或模型刷新失败:${R(_)}`),!0}B(`model-custom: ${V.id} 补录 ${Y} by ${J}(记录已持久化)`);for(let _ of D$.all)for(let[L,j]of _.modelPanels)if(j.sourceId===V.id&&(_!==$||L!==Q.panelId))_.modelPanels.delete(L);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await z(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let G=NQ($,W),K=G.find((_)=>_.model===Y);if(!K)return await z("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Q.panelId,{models:G,messageId:Q.cardMessageId}),K.unavailableReason||!K.efforts.length)return await H(A9(!0,Y,`**MISS**:${K.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Y} 已补录,能力尚未确认。`),!0;if(K.efforts.length===1){let _=await $.onModelEffortSelect(K.model,K.efforts[0].effort,Q.panelId,J,K.provider),L=(j)=>H(j.pending?M9(!0,j.message):j.ok?k8({sessionName:$.sessionName,provider:K.provider,model:K.model,effort:K.efforts[0].effort,scope:TQ($,K.provider??"codex")}):M9(!1,j.message),j.message);if(await L(_),_.completion)_.completion.then(L).catch(async(j)=>{let q=`模型补录后的切换结果呈现失败:${R(j)}`;B(`model-custom: ${q}`),await I($.chatId,`❌ ${q}`)});return!0}return await H(b8({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:K}),`✅ 模型 ${Y} 已补录成功。`),!0}async function RG($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:C8($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:C8($.sessionName)}}function cM($,Z){return O$(Z?.provider)?Z.provider:R2($)}function TQ($,Z){if(Z==="codex"&&$.proc?.isAlive()&&$.proc.provider===Z)return"Codex 需重启进程生效(发 restart)。";if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${y0(Z)} 时使用。`}async function TG($,Z,J="",Q="",Y=null){let V=Z.trim();if(!V)return await S($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=cM(V,Y),H=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===X);if(!H)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(H.unavailableReason)return{ok:!1,message:H.unavailableReason};if(H.enabled===!1)return{ok:!1,message:`${H.displayName} 未配置,请先点「启用」`};if(H.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(H.efforts.length===1)return EQ($,V,H.efforts[0].effort,J,Q,X);return{ok:!0,message:"",card:BZ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:H})}}async function EQ($,Z,J,Q="",Y="",V=""){if($.modelSettingsChangesClosed)return{ok:!1,message:"daemon 正在停止,本次模型选择未执行"};if($.modelSettingsChange?.proc===$.proc&&$.modelSettingsChange?.phase==="pending")return{ok:!1,message:"上一项模型设置仍在等待后端确认,本次选择未执行;请等待结果,取消切换请发 kill 或 restart。"};let X=Z.trim(),H=J.trim();if(!X)return{ok:!1,message:"模型为空"};let z=Q.trim(),W=$.modelPanels.get(z),G=O$(V)?V:W?.models.find((T)=>T.model===X)?.provider??R2(X);if(G==="dsh"){if(!q0(H))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(G==="claude"){if(!D0(H))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!Z$(H))return{ok:!1,message:"Codex reasoning effort 无效"};let K=H,_=W?.models.find((T)=>T.model===X&&(T.provider??"codex")===G);if(!_||!_.efforts.some((T)=>T.effort===K))return{ok:!1,message:`${y0(G)} · ${X}/${K} 不在选项中`};let L=$.tokenSource(_.sourceId);if(L?.modelCatalogState){if(!L.enabled||L.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${L.modelCatalogState.error??L.modelCatalogState.status}`};if(!L.models.some((T)=>T.model===X&&T.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let j=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,q=!$.processSourceMatches(L,X)||!!L?.modelEnvironmentRevision&&L.modelEnvironmentRevision($.currentModelLabel()??"")!==L.modelEnvironmentRevision(X),P=$.modelSelectionNeedsProcessStop(G,_.sourceId??$.selectedTokenSourceId,X,K);if($.currentProvider()===G&&!j&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!P&&!q)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${y0(G)} · ${X} / ${K}`,card:U9({sessionName:$.sessionName,provider:G,model:X,effort:K,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${y0(G)}`};let U=$.currentModelLabel()!==X||j,M=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((q||P)&&$.proc?.isAlive()&&M)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&U&&M)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!j&&!q&&!P){let x=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(X)??X:X;if(G==="codex")await $.proc.setModelSettings(x,K);else return await mM($,$.proc,X,x,K,z,_.sourceId)}await $.applyModelSelectionUnlocked(G,X,K,_.sourceId);let T=TQ($,G);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${y0(G)} · ${X} / ${K}`,card:U9({sessionName:$.sessionName,provider:G,model:X,effort:K,scope:T})}}catch(T){let x=`模型切换失败: ${R(T)}`;return B(`session "${$.sessionName}": set model settings failed: ${R(T)}`),{ok:!1,message:x}}}var AQ=20;var EG=O(()=>{G0();xQ();e();MQ();J1();G0();H$();u$();r();h()});import{createHash as lM}from"node:crypto";function iM($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function Z3($="default"){return kG(bG($))}function CG($="default"){return nM(bG($))}function bG($){return J$().map((Z)=>Z.forAccount?.($)??Z)}async function nM($){let Z=kG($),Q=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((z)=>z.tokenSourceId===V.id);if(X)return X;let H=await aM(V);return H===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:H}}))).filter((V)=>V!==null),Y=new Set(Q.map((V)=>V.tokenSourceId));return wG(Z.identities.filter((V)=>!Y.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Y.has(V.tokenSourceId)),...Q])}function aM($){let Z=xG.get($);if(Z&&(Z.expiresAt===null||Date.now()<Z.expiresAt))return Z.result;let J={expiresAt:null,result:oM($).finally(()=>{J.expiresAt=Date.now()+dM})};return xG.set($,J),J.result}async function oM($){let Z;try{let J=await $.readUsage();if(J.state==="ok")return null;Z=J.reason??`订阅可用性查询失败:${J.state}`}catch(J){Z=J instanceof Error?J.message:String(J)}return B(`agent identities ${$.id} MISS: ${Z}`),Z}function kG($){let Z=[],J=[];for(let Q of $)sM(Q,Z,J);return wG(Z,J)}function wG($,Z){return{catalogGeneration:lM("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function sM($,Z,J){let Q=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Q==="loading"||Q==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Q==="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 Y of $.models)Z.push(tM($,Y,Q))}function tM($,Z,J){let Q="ready",Y;if(!$.enabled)Q="source_disabled",Y="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Q="catalog_loading",Y="模型目录正在刷新";else if(J==="failed")Q="catalog_failed",Y=$.modelCatalogState?.error??"模型目录刷新失败";else if(Z.unavailableReason||!Z.efforts.length)Q="model_unavailable",Y=Z.unavailableReason??"effort MISS:上游未声明该后端支持的推理档位";return{id:iM($.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:SG($.defaultModel)===SG(Z.model),status:Q,...Y?{reason:Y}:{},spawnRevision:$.spawnRevision}}function SG($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var dM=1800000,xG;var w5=O(()=>{h();e();xG=new WeakMap});import{randomUUID as rM}from"node:crypto";async function yG($,Z){if(!Z.trim()){await I($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}hG(),await g2();let J=`agents_${rM()}`;if(J3.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()}),!await u($.chatId,fG(J)))await I($.chatId,"❌ agents 面板发送失败")}function vG($,Z,J){let Q=ZA($,J),Y=Number(Z);if(!Number.isInteger(Y))return JA("无效页码");let V=$A(Q.codexAccountId);return Q.page=Math.max(0,Math.min(V-1,Y)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:fG($)}}function fG($){let Z=J3.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=Z3(Z.codexAccountId),Q=Math.max(1,Math.ceil(J.identities.length/y5));Z.page=Math.min(Z.page,Q-1);let Y=Z.page*y5;return TZ({panelId:$,page:Z.page,totalPages:Q,catalog:J.identities.slice(Y,Y+y5),failures:J.sourceFailures})}function $A($){return Math.max(1,Math.ceil(Z3($).identities.length/y5))}function ZA($,Z){hG();let J=J3.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function JA($){return{ok:!1,message:$,card:_1({title:"agents",message:$,ok:!1})}}function hG(){let $=Date.now()-eM;for(let[Z,J]of J3)if(J.createdAt<$)J3.delete(Z)}var y5=8,eM=1800000,J3;var IG=O(()=>{H$();r();w5();e();J3=new Map});var bQ={};v$(bQ,{withTasklistLifecycleLock:()=>I5,tasklistNameForProject:()=>h5,reconcileTasklistDeletions:()=>XA,isTasklistAlreadyDeletedError:()=>gG,getTasklistBinding:()=>n$,enableTasklist:()=>SQ,deleteTasklistRemoteIdempotently:()=>mG,deleteTasklist:()=>CQ});import{existsSync as YA,readFileSync as VA}from"node:fs";function h5($){return`${$}[lodestar]`}function n$($){let Z=i$.get($);return Z?U4(Z):null}async function I5($,Z){let J=v5.get($)??Promise.resolve(),Q,Y=new Promise((X)=>{Q=X}),V=J.catch(()=>{}).then(()=>Y);v5.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Q(),v5.get($)===V)v5.delete($)}}function gG($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function mG($,Z=iZ){try{return await Z($),"deleted"}catch(J){if(gG(J))return"already_deleted";throw J}}async function SQ($,Z){return await I5($,async()=>{let J=n$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=h5($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await lZ(Z),V=await dZ(Q,Y),X={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Y,createdAt:V.createdAt};return f5($,X),U4(X)})}async function CQ($,Z){return await I5($,async()=>{let J=n$($);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},f5($,J);return await pG($,Z)})}async function pG($,Z){let J=n$($);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,f5($,J);try{if(await mG(Z)==="already_deleted")B(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(i$);return Y.delete($),cG(Y),i$.delete($),U4(J)}catch(Q){let Y=n$($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),f5($,Y);throw Q}}async function XA(){let $=[...i$.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await I5(J.projectName,()=>pG(J.projectName,J.guid)),B(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Q){Z.push(`${J.projectName}: ${Q instanceof Error?Q.message:String(Q)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function HA(){if(!YA(K3))return;try{let $=JSON.parse(VA(K3,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Q=J;if(typeof Q.guid!=="string"||!Q.guid||typeof Q.name!=="string"||!Q.name)continue;let Y={guid:Q.guid,name:Q.name,url:typeof Q.url==="string"?Q.url:"",projectName:Z,ownerOpenId:typeof Q.ownerOpenId==="string"?Q.ownerOpenId:"",createdAt:typeof Q.createdAt==="string"?Q.createdAt:void 0,deleting:zA(Q.deleting)};i$.set(Z,Y)}B(`tasklist: loaded ${i$.size} project bindings`)}catch($){B(`tasklist: load map failed: ${$}`)}}function zA($){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 f5($,Z){let J=new Map(i$);J.set($,U4(Z)),cG(J),i$.set($,U4(Z))}function cG($=i$){let Z={};for(let[J,Q]of $)Z[J]=U4(Q);o(K3,Z)}function U4($){return JSON.parse(JSON.stringify($))}var i$,v5;var kQ=O(()=>{V0();r();h();x0();i$=new Map,v5=new Map;HA()});function M1($,Z,J=!1){let Q=$.worktreeProjectName();return NZ({projectName:Q,tasklistName:h5(Q),binding:n$(Q),notice:Z,confirmDelete:J})}async function uG($){if(!await u($.chatId,M1($)))await I($.chatId,"❌ task 面板发送失败")}async function lG($){let Z=$.worktreeProjectName();try{let J=n$(Z),Q=await SQ(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:M1($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${R(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${R(J)}`),{ok:!1,message:Q,card:M1($,{type:"error",content:`❌ ${Q}`})}}}function dG($,Z){let J=$.worktreeProjectName(),Q=n$(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:M1($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:M1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:M1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function iG($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let V=`已删除 ${(await CQ(J,Q)).name}`;return{ok:!0,message:V,card:M1($,{type:"success",content:`✅ ${V}`})}}catch(Y){let V=`删除失败: ${R(Y)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${R(Y)}`),{ok:!1,message:V,card:M1($,{type:"error",content:`❌ ${V}`})}}}var nG=O(()=>{H$();r();h();kQ()});import{open as GA}from"node:fs/promises";import{basename as KA}from"node:path";function wQ($){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 a$($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class aG{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:X0,getToken:b$,retry:u1,wait:(Z)=>new Promise((J)=>setTimeout(J,Z)),intervalMs:250}){this.deps=$}request($,Z,J="GET",Q,Y){let V=this.queue.then(()=>this.deps.retry($,async()=>{Y?.throwIfAborted();let X=await this.deps.getToken(),H=Q?.(),z=H instanceof FormData,W=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(W>0)await this.deps.wait(W);Y?.throwIfAborted(),this.lastStartedAt=Date.now();let G=AbortSignal.timeout(jA),K=new AbortController,_=()=>K.abort(G.reason),L=()=>K.abort(Y.reason);G.addEventListener("abort",_,{once:!0}),Y?.addEventListener("abort",L,{once:!0});let j=K.signal;try{let q=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!z&&H!==void 0?{"Content-Type":"application/json"}:{}},...H!==void 0?{body:z?H:JSON.stringify(H)}:{},signal:j});return(await i2(q,$)).data}catch(q){if(j.aborted&&j.reason?.name==="TimeoutError")throw j.reason;throw q}finally{G.removeEventListener("abort",_),Y?.removeEventListener("abort",L)}}));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:a$(J?.token,"交付文件夹"),url:wQ(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return a$(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Q=a$(J?.token,"群文件夹");if(Q!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Q,url:wQ($.url),name:a$(J?.name,"群文件夹名称")}}async renameFolder($,Z,J){try{await this.request("同步群文件夹名称",`/drive/v1/files/${encodeURIComponent($.token)}?type=folder`,"PATCH",()=>({new_title:Z}),J)}catch(Y){if(Y instanceof S$&&Y.code===99991672)throw new S$("同步群文件夹名称需要应用身份权限 drive:file:upload(飞书错误码 99991672)",Y.status,Y.code);throw Y}let Q=await this.getFolder($,J);if(Q.name!==Z)throw Error("群文件夹名称更新未生效");return Q}async grantFolderAccess($,Z,J,Q){a$(Z,"交付群"),a$(J,"交付发起人");let Y=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let X 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("设置交付文件夹权限",Y,"POST",()=>X,Q);let V=await this.request("核对交付文件夹权限",Y,"GET",void 0,Q);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[X,H,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((G)=>G.member_type===X&&G.member_id===H)?.perm!==z)throw Error(`交付文件夹权限未生效:${X} / ${z}`)}async closeFileLinkSharing($,Z){a$($,"交付文件");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,Q){Q?.throwIfAborted();let Y=await GA($,"r");try{let V=await Y.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=KA($),H={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=BA){let j=await Y.readFile(),q=await Y.stat();if(j.length!==V.size||q.mtimeMs!==V.mtimeMs||q.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let P=new FormData;for(let[N,D]of Object.entries(H))P.append(N,String(D));return P.append("file",new Blob([Uint8Array.from(j)]),X),P},Q)}else{let j=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>H,Q),q=a$(j?.upload_id,"分片上传事务"),P=j?.block_size,N=j?.block_num;if(!Number.isSafeInteger(P)||P<=0||P>_A||!Number.isSafeInteger(N)||N!==Math.ceil(V.size/P))throw Error("云空间返回的分片策略无效");for(let U=0;U<N;U++){Q?.throwIfAborted();let M=Math.min(P,V.size-U*P),T=Buffer.alloc(M),x=0;while(x<M){let w=await Y.read(T,x,M-x,U*P+x);if(!w.bytesRead)throw Error("交付文件在分片读取时发生变化");x+=w.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let w=new FormData;return w.append("upload_id",q),w.append("seq",String(U)),w.append("size",String(M)),w.append("file",new Blob([Uint8Array.from(T)]),X),w},Q)}let D=await Y.stat();if(D.size!==V.size||D.mtimeMs!==V.mtimeMs||D.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:q,block_num:N}),Q)}let W=a$(z?.file_token,"已上传文件"),G={token:W,url:"",name:X,bytes:V.size};J(G),await this.closeFileLinkSharing(W,Q);let K=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:W,doc_type:"file"}],with_url:!0}),Q),_=K?.metas?.find((j)=>j.doc_token===W&&j.doc_type==="file");if(K?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let L={...G,url:wQ(_.url)};return J(L),L}finally{await Y.close()}}}var BA=20971520,_A=20971520,jA=60000,H2;var oG=O(()=>{u0();r();I8();H2=new aG});import{randomUUID as sG}from"node:crypto";import{basename as LA}from"node:path";class yQ{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:sG(),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:sG(),path:$,name:LA($),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(),Q=await this.deps.uploadFile($,J,(Y)=>{Z.file={...Y},Z.bytes=Y.bytes,this.save()},this.abort.signal);Z.file=Q,Z.bytes=Q.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(Q){this.snapshot.error=Q instanceof Error?Q.message:String(Q)}if(!this.abort.signal.aborted)try{await this.deps.reportError(`❌ 文件交付失败:${Z.name}
241
+ ${Z.error}`)}catch(Q){this.snapshot.error=`错误提示发送失败:${String(Q)}`}}})}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(Q){this.snapshot.error+=`;${String(Q)}`}return await this.deps.reportError(`❌ ${this.snapshot.error}${this.snapshot.folderAccessReady?`
242
+ 已上传文件所在文件夹:${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 tG=()=>{};class vQ{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=C$(Z),Q=this.load(),Y=Q.workspaces[J]?.enabled;if(Y===void 0){let X=new Set(this.legacyChats($,J).map((H)=>Q.groups[H].legacyEnabled));if(X.size>1)throw Error("同一工作目录的旧群文件交付设置冲突,请发送 files on 或 files off 统一设置");if(X.size)Y=X.values().next().value,this.commitMode($,J,Y)}let V=this.load().groups[$]?.folder;return{enabled:Y??!1,...V?{folder:structuredClone(V)}:{}}}mode($,Z){return this.get($,Z).enabled?"drive":"chat"}enable($,Z,J){let Q=C$(Z);return this.exclusive(`workspace:${Q}`,()=>this.exclusive(`chat:${$}`,async()=>{return await this.prepare($,J,!0),this.commitMode($,Q,!0),this.get($,Z)}))}disable($,Z){let J=C$(Z);return this.exclusive(`workspace:${J}`,async()=>{return this.commitMode($,J,!1),this.get($,Z)})}resolveFolder($,Z){return this.exclusive(`chat:${$.chatId}`,()=>this.prepare($.chatId,$.managerOpenId,!0,Z))}bindExisting($,Z,J,Q){return this.exclusive(`chat:${$}`,async()=>{let Y=this.load().groups[$];if(Y?.folder&&Y.folder.token!==Q.token)throw Error("本群已经绑定其他文件夹");let V=await this.deps.getFolder(Q);return this.commitFolder($,V),await this.prepare($,J,!1),this.get($,Z)})}async prepare($,Z,J,Q){if(Q?.throwIfAborted(),!$.trim()||!Z.trim())throw Error("无法确认交付群或管理权限接收人");let Y=await this.deps.getChatName($,Q);if(!Y.trim())throw Error("群名称 MISS");let V=this.load().groups[$]?.folder;if(!V){if(!J)throw Error("本群尚未绑定云空间文件夹");V={...await this.deps.createFolder(Y,Q),name:Y},this.commitFolder($,V)}let X=await this.deps.getFolder(V,Q);if(X.token!==V.token)throw Error("云空间返回的文件夹与本群绑定不一致");if(V=X.name===Y?X:await this.deps.renameFolder(X,Y,Q),V.name!==Y)throw Error("文件夹名称尚未与群名同步");return this.commitFolder($,V),await this.deps.grantFolderAccess(V,$,Z,Q),V}exclusive($,Z){let Q=(this.locks.get($)??Promise.resolve()).then(Z),Y=Q.then(()=>{},()=>{});return this.locks.set($,Y),Y.then(()=>{if(this.locks.get($)===Y)this.locks.delete($)}),Q}load(){if(this.state)return this.state;let $=this.deps.read();if($===void 0)return this.state={version:2,workspaces:{},groups:{}};let Z=JSON.parse($);if(![1,2].includes(Z?.version)||!Q3(Z.groups)||Z.version===2&&!Q3(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Q,Y]of Object.entries(Z.workspaces??{})){if(!Q3(Y)||typeof Y.enabled!=="boolean"||C$(Q)!==Q)throw Error("工作目录文件交付开关无效");J.workspaces[Q]={enabled:Y.enabled}}for(let[Q,Y]of Object.entries(Z.groups)){if(!Q||!Q3(Y))throw Error("群文件夹绑定无效");let V=Z.version===1?Y.enabled:Y.legacyEnabled;if((Z.version===1||V!==void 0)&&typeof V!=="boolean")throw Error("群文件交付开关无效");if(V&&!Y.folder)throw Error("已启用的旧群缺少文件夹绑定");if(Y.folder!==void 0)qA(Y.folder);J.groups[Q]={...Y.folder?{folder:structuredClone(Y.folder)}:{},...V===void 0?{}:{legacyEnabled:V}}}return this.state=J}legacyChats($,Z){return Object.entries(this.load().groups).filter(([J,Q])=>{if(Q.legacyEnabled===void 0)return!1;if(J===$)return!0;let Y=this.deps.workDirForChat(J);return Y!==void 0&&C$(Y)===Z}).map(([J])=>J)}commitMode($,Z,J){let Q=structuredClone(this.load());Q.workspaces[Z]={enabled:J};for(let Y of this.legacyChats($,Z))delete Q.groups[Y].legacyEnabled;this.commit(Q)}commitFolder($,Z){let J=structuredClone(this.load());J.groups[$]={...J.groups[$],folder:Z},this.commit(J)}commit($){this.deps.write($),this.state=$}}function Q3($){return!!$&&typeof $==="object"&&!Array.isArray($)}function qA($){if(!Q3($)||typeof $.token!=="string"||!$.token.trim()||typeof $.name!=="string"||!$.name.trim()||typeof $.url!=="string")throw Error("群文件夹绑定无效");let Z=new URL($.url);if(Z.protocol!=="https:"||Z.username||Z.password)throw Error("群文件夹链接无效")}var rG=O(()=>{u8()});import{join as FA}from"node:path";import{readFileSync as PA}from"node:fs";function eG($){return new yQ($,{resolveFolder:(Z,J)=>M4.resolveFolder(Z,J),uploadFile:(Z,J,Q,Y)=>H2.uploadFile(Z,J,Q,Y),sendCard:(Z)=>u($.chatId,h6(Z)),persist:(Z)=>o(FA(FY,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await S($.chatId,Z))throw Error(Z)}})}var M4;var $K=O(()=>{r();oG();tG();V8();V0();x0();h();rG();u8();M4=new vQ({read:()=>{try{return PA(_7,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>o(_7,$),workDirForChat:($)=>{let Z=[...K0].filter(([,Y])=>Y===$).map(([Y])=>Y),J=B0.get($);if(!Z.length&&J)Z.push(J);let Q=new Set(Z.map((Y)=>C$(r2(Y))));if(Q.size>1)throw Error(`旧文件交付群绑定了多个工作目录: ${$}`);return Q.values().next().value},getChatName:($,Z)=>H2.getChatName($,Z),createFolder:($,Z)=>H2.createFolder($,Z),getFolder:($,Z)=>H2.getFolder($,Z),renameFolder:($,Z,J)=>H2.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Q)=>H2.grantFolderAccess($,Z,J,Q)})});async function ZK($,Z,J,Q,Y,V){let X,H="",z="";try{switch(Q.trim().toLowerCase()){case"":case"status":X=Y.get($);break;case"on":X=await Y.enable($,J),H="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Y.disable($),H="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(G){z=G instanceof Error?G.message:String(G);try{X=Y.get($)}catch{X=void 0}}let W=I6({groupName:Z,workDir:V,settings:X,notice:H,error:z});if(!await Y.sendCard(W))await Y.reportError(`❌ 文件交付设置卡发送失败${z?`:${z}`:""}`)}var JK=O(()=>{V8()});function QK($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
243
+ `)}function YK($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",QK(Z),"- 文件交付约定由 Lodestar 按工作目录设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写工作目录配置。"}`,J[$],...DA].join(`
244
+ `)}function VK($){return`[Lodestar 文件交付约定更新]
244
245
  以下约定从本轮起完整替换此前的文件交付约定:
245
- ${hW($)}`}var iU;var OY=O(()=>{iU=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});function Z2($){return y8(v$($.sessionName)??$.sessionName)}function P4($){return n2(Z2($))}function pW($){return n2($.sessionName)}function cW($,Z,J=$.currentProvider()){let Y=IW(J,Z),Q=o9($);return Q?`${Y}
246
- ${Q}`:Y}function uW($,Z){return o9($)??""}function NY($){return o9($)?"已载入wt特殊约定":null}function lW($,Z){let J=NY($);return J?`${Z}
247
- ${J}`:Z}function o9($){let Z=Z2($),J=xH($.workDir,P4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
248
- `)}async function dW($,Z,J){if(!Z){await RY($);return}let Y=I1(Z);if(!Y){await E($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await E($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=Z2($),V=P4($);try{await k8(V,async()=>{let X;try{X=CH(V,Q,Y)}catch(H){await E($.chatId,`❌ wt 失败: ${N(H)}`);return}try{let H=await XJ(X.chatName,J),z=H.created?"已创建":H.joined?"已加入":"已在群内";if(!await u($.chatId,P9({slug:Y,branch:X.branch,status:z})))await w($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await u(H.chatId,P9({slug:Y,branch:X.branch,status:"就绪",body:"开始吧。"})))await w(H.chatId,`❌ wt 卡片失败: ${Y}`)}catch(H){await E($.chatId,`❌ wt 已建,拉群失败: ${N(H)}`)}})}catch(X){await E($.chatId,`❌ wt 失败: ${N(X)}`)}}async function iW($,Z){let J=Z2($),Y=P4($);return await k8(Y,async()=>{return await nU(J,Y,Z)})}async function nU($,Z,J){let Y=SH(Z,$),Q=Y.filter((H)=>H.state==="merged"&&!H.mounted).length,V=Y.filter((H)=>H.state!=="merged"||H.mounted),X=await p8();return XZ({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:V.map((H)=>{let z=X.get(H.chatName)??[],G=G0.get(H.chatName),W=G&&z.includes(G)?G:z.length===1?z[0]:null;return{slug:H.slug,chatName:H.chatName,branch:H.branch,state:H.state,path:H.worktreePath??H.expectedPath,mounted:H.mounted,dirtyCount:H.dirtyCount,statusLine:H.statusLine,error:H.error,chatId:W,duplicateChatCount:z.length}})})}async function RY($){try{let Z=await iW($);if(!await u($.chatId,Z))await w($.chatId,"❌ wt 列表失败")}catch(Z){await E($.chatId,`❌ wt 列表失败: ${N(Z)}`)}}async function mW($,Z,J,Y){try{return{ok:Z,message:J,card:await iW($,{type:Y,content:J})}}catch(Q){let V=`列表刷新失败: ${N(Q)}`;return B(`session "${$.sessionName}": wt action panel refresh failed: ${N(Q)}`),{ok:!1,message:`${J}
249
- ${V}`,card:P9({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function nW($,Z){let J=I1(Z);if(!J)return mW($,!1,"❌ 名称无效","error");let Y=Z2($),Q=P4($),V;try{V=await k8(Q,async()=>{let X=u2(Y,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};SZ(Q,Y,J);let H=await zJ(X),z=bH(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",H.disbanded?"group removed":"group missing",z.branch].join(`
250
- `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${N(X)}`,type:"error"}}return mW($,V.ok,V.message,V.type)}var aW=O(()=>{OY();Q$();r();f();yZ()});import{closeSync as oU,openSync as sU,readSync as tU,readdirSync as rU,statSync as eU}from"node:fs";import{randomUUID as EY}from"node:crypto";import{join as $A}from"node:path";function S7($){return v$($.sessionName)??$.sessionName}function sW($){let Z=$J($,TY);return TY.add(Z),Z}function tW($){TY.delete($)}function q4($){let Z=oW.get($);if(!Z)Z=new Map,oW.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let V=Q.status==="consumed"?YA:JA,X=Q.consumedAt??Q.createdAt;if(J-X>V)Z.delete(Y)}return Z}function VA($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function rW($,Z,J,Y){let Q={id:EY(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:S7($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return q4($).set(Q.id,Q),Q}function xY($,Z,J,Y,Q){let V=q4($).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||!VA(V.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let X=V.choices.get(Y);if(!X)return{error:"无效的选择项,这张卡可能已过期"};return V.status="processing",{panel:V,choice:X}}function x7($){$.status="consumed",$.consumedAt=Date.now()}function XA($){return{kind:"fork",source:$.source,through:$}}function HA($){return o2($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function zA($){let Z=s2($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return L0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function GA($){let Z=h3($),J;try{J=rU(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(P2("claude",V))continue;let X=$A(Z,Q),H;try{H=eU(X).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${z?.message??z}`)}Y.push({provider:"claude",sessionId:V,cwd:$,preview:KA(X),ts:H})}return Y.sort((Q,V)=>V.ts-Q.ts)}function WA($){let Z=$.slice().sort((Q,V)=>V.ts-Q.ts),J=Date.now()-ZA,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(QA,Math.max(10,Y)))}function KA($){let Z="",J=null;try{J=sU($,"r");let Q=Buffer.alloc(65536),V=tU(J,Q,0,65536,0);Z=Q.subarray(0,V).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)oU(J)}let Y="";for(let Q of Z.split(`
251
- `)){let V=Q.trim();if(!V)continue;let X;try{X=JSON.parse(V)}catch{continue}if(X.type==="queue-operation"&&X.operation==="enqueue"&&typeof X.content==="string"){let H=X.content.trim();if(H)return H.slice(0,80)}if(!Y&&X.type==="user"&&X.message){let H=BA(X.message);if(H)Y=H}}return Y.slice(0,80)}function BA($){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 eW($,Z,J){if(!J){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=HA($),Q=zA($),V=new Map,X=[];for(let W=0;W<Y.length;W++){let K=Y[W];if(W===0&&Q===null)continue;let _=EY(),L=W===0?Q:XA(Y[W-1].checkpoint);V.set(_,{kind:Z,launch:L,branchBase:Q,seedAnchors:Y.slice(0,W),writes:Y.slice(W).flatMap((j)=>j.writes)}),X.push({choiceId:_,preview:K.preview,ts:K.ts})}X.reverse();let H=rW($,Z,J,V),z=zZ({projectName:S7($),panelId:H.id,mode:Z,entries:X}),G;try{G=await u($.chatId,z)}catch(W){throw q4($).delete(H.id),W}if(!G)q4($).delete(H.id),await w($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function $K($,Z){return eW($,"fork",Z)}function ZK($,Z){return eW($,"back",Z)}async function JK($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():GA($.workDir)}catch(z){await w($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Y=new Map,Q=WA(J).map((z)=>{let G=EY();return Y.set(G,{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:G,preview:z.preview,ts:z.ts}}),V=rW($,"resume",Z,Y),X=GZ({projectName:S7($),panelId:V.id,entries:Q}),H;try{H=await u($.chatId,X)}catch(z){throw q4($).delete(V.id),z}if(!H)q4($).delete(V.id),await w($.chatId,"❌ rs 历史列表发送失败")}async function YK($,Z){if(!Z){await E($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await E($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=sW(S7($));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{tW(J)}if(!Y.ok){await E($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await E($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function QK($){if(!v$($.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 VK($,Z,J,Y){let Q=xY($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:X}=Q;try{if(X.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let H=sW(V.baseName);B(`session-temp: fork ${$.sessionName} → ${H} (${X.launch.kind})`),await E($.chatId,`\uD83D\uDD31 正在分叉到 ${H}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:H,userOpenId:Y,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{tW(H)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${H};原会话和磁盘文件未回滚`}}catch(H){return{ok:!1,message:`分叉失败: ${H instanceof Error?H.message:H}`}}finally{x7(V)}}async function XK($,Z,J,Y){let Q=xY($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:X}=Q;try{if(X.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let H="";try{if(!await u($.chatId,WZ({projectName:V.baseName,entries:X.writes})))H=";文件变更记录卡发送失败"}catch(W){H=`;文件变更记录卡发送失败: ${W instanceof Error?W.message:W}`}if(B(`session-temp: back ${$.sessionName} (${X.launch.kind}, writes=${X.writes.length})`),!await $.rollbackTo(X.launch,{anchors:X.seedAnchors,base:X.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${H}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${H}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${O0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${H}`}}catch(H){return{ok:!1,message:`回退失败: ${H instanceof Error?H.message:H}`}}finally{x7(V)}}async function HK($,Z,J,Y){let Q=xY($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:V,choice:X}=Q;if(X.kind!=="resume")throw x7(V),Error("resume panel contained a non-resume choice");let H=X.launch.source.sessionId,z=$.lastSessionId,G=(K,_)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:H,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:z,newSessionId:K,bindingState:_}),W=(K,_,L,j=null)=>({ok:K,message:_,resumePresentation:G(j,L)});try{if($.isRunning())return W(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(X.sourceStatus==="active")return W(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(B(`session-temp: history fork ${$.sessionName} ← ${X.launch.source.provider} ${H}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:z}:null}))return W(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return W(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let _=$.lastSessionId;if(!_)return W(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===H||z&&_===z)return W(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return W(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(K){return W(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{x7(V)}}var ZA=86400000,JA=1800000,YA=3600000,QA=40,oW,TY;var zK=O(()=>{r();Q$();f();S2();w4();M1();oW=new WeakMap,TY=new Set});import{existsSync as GK}from"node:fs";import{randomBytes as SY,timingSafeEqual as jA}from"node:crypto";import{isAbsolute as LA}from"node:path";function bY($,Z=new Set){if($ instanceof N2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=bY(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return bY($.cause,Z);return null}function PA($){return $.itemId||$.turnId||"__latest__"}function WK($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function qA($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function FA($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function k7(){return v.runtime?.live_elapsed??"bucket"}function _K($,Z){return`${$} (${T2(Date.now()-Z,k7()).label})`}var KK="Thinking...",DA="Writing...",MA="Working...",CY=1e4,C7=720000,UA=50,AA=256,b7=1e4,BK=250,q$;var LY=O(()=>{w4();f4();j0();U1();$6();j0();S0();T6();FJ();Z0();w0();J4();S2();f$();Q$();r();f();Q0();t6();A$();xz();SJ();CJ();gz();rz();_G();W7();PG();sG();rG();HW();FW();EW();wW();fW();OY();aW();zK();M1();q$=class q${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=SY(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;modelSettingsChange=null;modelSettingsChangesClosed=!1;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??qz(),q$.all.add(this);let Y=JJ($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=e0(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)B(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=X1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=t2($);if(V)if(this.selectedProvider!=="claude")l0($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{L0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,H=this.lastSessionRef,z=!X&&H?.provider==="claude"&&H.cwd===this.workDir&&H.sessionId!==V.launch.source.sessionId&&H.sessionId!==V.previousSessionId;if(!X&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`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(y0(this.proc)).name}:{}}}get workDir(){return pW(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 L6(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?y0(this.proc):this.codexStartAccountOverride??k.selected(this.sessionName)}tokenSource($){let Z=e0($);return Z?.forAccount?V0($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...this.codexAccountId()===m?{}:{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=e0($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)l0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=X1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,z1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId);let J=$.codexAccountId??m;if($.codexAccountAutomatic)k.selectAuto(this.sessionName);else if(k.selected(this.sessionName)!==J)k.select(this.sessionName,J)}dshEffortForSpawn(){if(_0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&U$($,this.selectedModel??$.defaultModel);if(!Z||!_0(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)=>!P2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!E9(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?(H)=>Z.spawnEnv(H):void 0,Y=new R2({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(H){V=H}let X=null;try{await Y.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${N(V)}; ${N(X)}`);if(V)throw V;if(X)throw X;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=I3(this.workDir,$.sessionId);if(!GK(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${O0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!E9(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 R2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(H)=>Y.spawnEnv(H):void 0}),V=null;try{Z=await Q.readConversationRef($.sessionId)}catch(H){V=H,Z=$}let X=null;try{await Q.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${N(V)}; cleanup=${N(X)}`);if(V)throw V;if(X)throw X}return L0({kind:"resume",source:Z},this.selectedProvider,this.workDir),O9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...q$.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 t0(this.selectedEffort)?this.selectedEffort:u4}return u4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&F0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=U$($,this.selectedModel??$.defaultModel);if(!F0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return i$}currentModelLabel(){if(this.modelSettingsChange?.proc===this.proc&&this.modelSettingsChange.phase==="failed")return this.modelSettingsChange.confirmedModel;return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){if(this.modelSettingsChange?.proc===this.proc&&this.modelSettingsChange.phase==="failed")return this.modelSettingsChange.confirmedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude")return this.selectedEffort??U$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?i$:u4)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider;if($&&this.modelSettingsChange?.proc===$&&this.modelSettingsChange.phase==="failed")return{provider:Z,model:this.modelSettingsChange.confirmedModel,effort:this.modelSettingsChange.confirmedEffort};let J=!$||$.provider===this.selectedProvider,Y=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Q=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?i$:u4);return{provider:Z,model:Y,effort:Q}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return Y0($,T.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:T.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return b6($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return s0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(L0($.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=SY(32).toString("base64url");let Z={LODESTAR_AGENT_URL:o3(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:this.agentCapability,LODESTAR_AGENT_SESSION:this.sessionName,LODESTAR_AGENT_ROLE:"main"},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});L0(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,X=this.currentTurn?.fileDeliveryMode??this.getFileDeliveryMode(),H=$9({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(X),profile:U9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:z2},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),this.procFileDeliveryModes.set(H.process,X),H.process}async applyModelSelection($,Z,J,Y){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Y))}async applyModelSelectionUnlocked($,Z,J,Y){let Q=this.selectedProvider,V=Y??this.selectedTokenSourceId,X=e0(V),H=X?Z||null:$==="codex"?null:Z,z=X?J??U$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,H);let G=Q!==$?{anchors:o2(this.sessionName).slice(),base:s2(this.sessionName),pending:t2(this.sessionName)}:null;if(G)l0(this.sessionName,[],null,null);try{z1(this.sessionName,$,H,z,V)}catch(W){if(G)try{l0(this.sessionName,G.anchors,G.base,G.pending)}catch(K){throw AggregateError([W,K],`model selection write failed: ${N(W)}; conversation state restore failed: ${N(K)}`)}throw W}if(G)this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=V,this.selectedModel=H,this.selectedEffort=z,this.lastSessionRef=X1(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null}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()===k2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===k2($,Z)}modelSelectionNeedsProcessStop($=this.selectedProvider,Z=this.selectedTokenSourceId,J=this.selectedModel){let Y=this.proc;return!!Y?.isAlive()&&(this.blockedProc===Y||Y.provider!==$||Y.tokenSourceId!==Z||!this.processSourceMatches(this.tokenSource(Z),J))}async stopIdleMismatchedProcessUnlocked($=this.selectedProvider,Z=this.selectedTokenSourceId,J=this.selectedModel){if(!this.proc||!this.modelSelectionNeedsProcessStop($,Z,J))return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let Y=this.proc;B(`session "${this.sessionName}": stop idle ${Y.provider} process before switching to ${$}`),this.beginProcStop(Y),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let Q=await this.settleProcResumableState(Y),V=null;try{await Y.kill()}catch(z){V=z}Q=await this.settleProcResumableState(Y);let X=this.finishProcStop(Y,V);this.opts.onLifecycleChange?.();let H=[...V?[V]:!X?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Q?[Error(Q)]:[]];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;B(`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()}catch(X){Y=X}J=await this.settleProcResumableState(Z);let Q=this.finishProcStop(Z,Y);this.opts.onLifecycleChange?.();let V=[...Y?[Y]:!Q?[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,X=()=>{if(V)return;this.replaceFooterContent($,J(_K(Q,Y)))},H=null,z=()=>{if(V)return;let{nextDelayMs:G}=T2(Date.now()-Y,k7());H=setTimeout(()=>{X(),z()},Math.max(1,Math.ceil(G)))};return X(),z(),{setStatus(G){Q=G,X()},stop(){if(V=!0,H)clearTimeout(H)},elapsedSec(){return(Date.now()-Y)/1000}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=e6({sessionName:this.sessionName,title:$,status:_K(Z,Y),template:J}),V=await u(this.chatId,Q);if(!V)return B(`session "${this.sessionName}": status card send failed title=${$}`),await w(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let X;try{X=await L$(V)}catch(H){return B(`session "${this.sessionName}": status card id_convert failed title=${$}: ${H}`),await w(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return X$(X,1),{cardId:X,title:$,timer:this.startFooterTimer(X,Z,(H)=>K9($,H))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=K9($.title,`${Z} (${D0(J)})`);await G1($.cardId);let Q=await A0($.cardId,T.footer,this.footerElement(Y));v0($.cardId);let V=await R0($.cardId,b1({durationSec:J,suffix:Z}));if(Q&&V)await H$($.cardId);else{let X=`footer=${Q?"ok":"MISS"}, settings=${V?"ok":"MISS"}`;B(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${X}`),await w(this.chatId,`⚠️ 状态卡片终态写入失败 (${X}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Y;this.lifecycleTail=new Promise((V)=>{Y=V}),await J;let Q=++this.lifecycleSequence;B(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),B(`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((X)=>{Y=X}),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.modelSettingsChange?.cancel("原进程已更换"),this.modelSettingsChange=null,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.modelSettingsChange?.cancel("原进程已退出"),this.modelSettingsChange=null,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($){if(this.modelSettingsChange?.proc===$)this.modelSettingsChange.cancel("原进程正在停止"),this.modelSettingsChange=null;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&&jA(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",B(`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,l0(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=V0("codex-sub",$)?.defaultModel||null;l0(this.sessionName,[],null,null),z1(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=X1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")z1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&y0(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"&&!E9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,P$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!GK(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await E(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{_J(this.workDir)}catch(W){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${W}`),Z)await E(this.chatId,`❌ 创建项目失败: ${W}`);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 N1();Q=this.spawnAgent()}catch(W){let K=`${this.backendLabel()} 启动失败: ${N(W)}`;if(B(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await E(this.chatId,`❌ ${K}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let V=this.backendLabel(),X=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,BK):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let H,z=null;try{Q.sendInitialize(),H=Q.initializationPromise?.()}catch(W){H=void 0,z=W}let G=z?{state:"error",error:z}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(H),()=>{B(`session "${this.sessionName}": codex init still pending after ${CY/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(G.state==="error"||G.state==="exit"){let W=G.error?N(G.error):G.state;B(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${W}`);let _=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,L=`❌ ${V} 启动失败: ${W}${_}`;if(J?.(L),Z)await E(this.chatId,L);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="timeout"){B(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${C7/1000}s)`);let K=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${C7/1000} 秒内初始化事务未完成${K}`;if(J?.(_),Z)await E(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let W=`${V} 启动期间已退出`;if(B(`session "${this.sessionName}": ${W}`),J?.(`❌ ${W}`),Z)await E(this.chatId,`❌ ${W}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,P$({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let W=this.modelLine();await E(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),W].filter(Boolean).join(`
252
- `))}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=(H,z)=>{if(Y)return;Y=!0,clearTimeout(V),clearTimeout(X),J({state:H,error:z})},V=setTimeout(()=>{if(Y)return;try{Z?.()}catch(H){Q("error",H)}},CY),X=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${C7/1000}s`))},C7);$.then(()=>Q("init"),(H)=>Q("error",H)),this.proc?.quotaWaitPromise?.().then(()=>Q("waiting_quota"),(H)=>Q("error",H))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(G,W)=>{if(Y)return;Y=!0,clearTimeout(V),$.off("init",X),$.off("error",H),$.off("exit",z),J({state:G,error:W})},V=setTimeout(()=>Q("ready"),Z),X=()=>Q("init"),H=(G)=>Q("error",G),z=(G)=>Q("exit",G);$.once("init",X),$.once("error",H),$.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;B(`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),X=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),B(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((F)=>{B(`session "${this.sessionName}": stop current main-card close failed: ${N(F)}`)});let H=this.waitForTurnCloses().catch((F)=>B(`session "${this.sessionName}": stop main-card close failed: ${N(F)}`));this.beginProcStop(Q),this.status="stopped";let z=[];try{this.opts.onLifecycleChange?.()}catch(F){z.push(F),B(`session "${this.sessionName}": stop intent lifecycle write failed: ${N(F)}`)}let G=Q.conversationMaterializationBarrier?.();if(G){try{await G}catch(F){X=`Codex 会话落盘确认失败: ${N(F)}`}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 W=null;try{await Q.kill()}catch(F){W=F}let K=Q.conversationMaterializationFailure?.();if(K&&Q.isConversationResumable?.()!==!0)X=`Codex 会话落盘确认失败: ${N(K)}`;V=this.persistResumableSessionId(!1,Q,!1);let L=(await Promise.allSettled([this.resetBackgroundTasks(),H])).filter((F)=>F.status==="rejected").map((F)=>F.reason);for(let F of L)B(`session "${this.sessionName}": stop terminal cleanup failed: ${N(F)}`);let j=this.finishProcStop(Q,W);try{this.opts.onLifecycleChange?.()}catch(F){z.push(F),B(`session "${this.sessionName}": stop final lifecycle write failed: ${N(F)}`)}let q=[...W?[W]:[],...!j&&!W?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...L,...z,...V?[Error(V)]:[],...X&&Q.isConversationResumable?.()!==!0?[Error(X)]:[]];if(q.length===1)throw q[0];if(q.length>1)throw AggregateError(q,`stop failed: ${q.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,X=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)X=this.pendingConversationMaterialization,H1(this.sessionName,null),this.pendingConversationMaterialization=null;let H=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!H&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(C){let I=this.invalidateMissingCodexResume(z.sessionId,C,J),c=I?`❌ 旧会话不可恢复: ${N(C)};${I}`:`❌ 旧会话 cwd 校验失败: ${N(C)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Q?.(c),Y)await E(this.chatId,c);return!1}let G=z?.sessionId??null,W=H&&H.kind!=="fresh"?H.source.sessionId:G,K=W?O0(W):"",_=null,L=(C=this.proc)=>{if(!$||H||C?.provider!=="codex"||C.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,C,!1),z=this.lastSessionRef,G=z?.sessionId??null,W=G,K=W?O0(W):""},j=null;if(!Q&&Y&&$&&G){let C=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(j=await this.openStatusCard("restart",C),j)Q=(I)=>this.setStatusCard(j,I)}let q=Y&&!j,F=async(C)=>{if(j)await this.closeStatusCard(j,C)},R=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||i5(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let C of this.fileDeliveries)C.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((C)=>{B(`session "${this.sessionName}": restart current main-card close failed: ${N(C)}`)});let D=this.waitForTurnCloses().catch((C)=>B(`session "${this.sessionName}": restart main-card close failed: ${N(C)}`)),U=null,A=null;if(this.proc){let C=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(C.provider)}`),A=C,this.beginProcStop(C);let I=C.conversationMaterializationBarrier?.();if(I)try{await I}catch(l){_=`Codex 会话落盘确认失败: ${N(l)}`}if(L(C),$&&!H&&_&&!R&&C.isAlive()){if(this.stoppingProc===C)this.stoppingProc=null;this.status=V;let l=`❌ ${this.backendLabel(C.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(B(`session "${this.sessionName}": abort restart before kill: ${_}`),Q?.(l),q)await E(this.chatId,l);return await F(l),!1}try{await C.kill()}catch(l){U=l}let c=C.conversationMaterializationFailure?.();if(c&&C.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${N(c)}`;L(C)}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 S=(await Promise.allSettled([this.resetBackgroundTasks(),D])).filter((C)=>C.status==="rejected").map((C)=>C.reason);for(let C of S)B(`session "${this.sessionName}": restart terminal cleanup failed: ${N(C)}`);let h=A?this.finishProcStop(A,U):!0,y=[...U?[`kill=${N(U)}`]:[],...!h&&!U?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...S.map((C)=>`cleanup=${N(C)}`),..._?[`resume=${_}`]:[]];if(y.length>0&&X)try{H1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(C){y.push(`pendingRestore=${N(C)}`)}if(y.length>0){let C=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${y.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(C),q)await E(this.chatId,C);return await F(C),!1}let g=H?.kind==="resume"||H?.kind==="fork";if($&&z||g){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let C;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&k.preferred(this.sessionName)===null)await N1();C=this.spawnAgent(z??void 0)}catch(a){let B0=`❌ ${this.backendLabel()} 恢复失败: ${N(a)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${N(a)}`),Q?.(B0),q)await E(this.chatId,B0);return this.status="stopped",this.opts.onLifecycleChange?.(),await F(B0),!1}this.attachProc(C);let I=this.backendLabel(),c=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(C,BK):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${I} 恢复启动`:`⏳ 等待 ${I} init 确认`);let l,M=null;try{C.sendInitialize(),l=C.initializationPromise?.()}catch(a){l=void 0,M=a}let b=M?{state:"error",error:M}:this.selectedProvider==="claude"?await c:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${CY/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${I} init 确认 thread=${K}`))});if(b.state==="error"||b.state==="exit"||b.state==="timeout"){let a=b.state==="error"?this.invalidateMissingCodexResume(W,b.error,J):null,B0=[b.error?N(b.error):b.state,a].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${B0}`);let $3=await this.stopOwnedProc(C,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,V2=b.state==="timeout"?`❌ ${I} 恢复超时${$3}`:`❌ ${I} 恢复失败: ${B0}${$3}`;if(Q?.(V2),q)await E(this.chatId,V2);return this.status="stopped",this.opts.onLifecycleChange?.(),await F(V2),!1}if(this.proc!==C||!C.isAlive()){let a=`❌ ${I} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(a),q)await E(this.chatId,a);return this.detachProc(C),this.status="stopped",this.opts.onLifecycleChange?.(),await F(a),!1}let d=this.withModel(this.withWorktreeInstructionNotice(b.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&b.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Q?.(d),q)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 F(d)}catch(a){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${N(a)}`),await w(this.chatId,`⚠️ ${d}
253
- 状态卡收尾失败: ${N(a)}`)}return!0}else{if($&&!H){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),q)await E(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{L0($,this.selectedProvider,this.workDir);let J=t2(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)H1(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)H1(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{H1(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()=>{L0($,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,X=this.lastSessionRef,H=o2(this.sessionName).slice(),z=s2(this.sessionName),G=t2(this.sessionName),W={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,_=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,a2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)O9(this.sessionName,X);else a2(this.sessionName,this.selectedProvider);l0(this.sessionName,H,z,G),this.pendingConversationMaterialization=G,this.turnCounter=W.turnCounter,this.currentGoal=W.currentGoal,this.cumStats=W.cumStats,this.lastTurnDelta=W.lastTurnDelta,this.currentTurnUsageBaseline=W.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=W.currentTurnUsageBaselineKnown,this.lastTurnUsage=W.lastTurnUsage,this.usageTotalsSeedUnknown=W.usageTotalsSeedUnknown},L=!1;if(Y?.pendingLaunch)l0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,L=!0;this.pendingConversationLaunch=$;let j=(q)=>{K=X?.provider==="codex"&&X.sessionId===q};try{let q;try{q=$.kind==="fresh"?await this.restartUnlocked(!1,J,j):await this.restartUnlocked(!0,J,j)}catch(F){let R=null,D=this.proc&&this.proc!==Q?this.proc:null;if(D)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(S){R=S}let U=!D||this.proc!==D&&!D.isAlive();if(!U&&!R)R=Error("replacement process stop was not confirmed");let A=null;if(U)try{_()}catch(S){A=S}let x=[F,...R?[R]:[],...A?[A]:[]];if(x.length===1)throw F;throw AggregateError(x,`rollback launch and cleanup failed: ${x.map(N).join("; ")}`)}if(!q)return _(),!1;if(Y)try{if(!L)l0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(F){let R=null,D=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(S){R=S}let U=!D||this.proc!==D&&!D.isAlive();if(!U&&!R)R=Error("replacement process stop was not confirmed");let A=null;if(U)try{_()}catch(S){A=S}let x=[F,...R?[R]:[],...A?[A]:[]];if(x.length===1)throw F;throw AggregateError(x,`rollback branch commit failed: ${x.map(N).join("; ")}`)}return q}finally{this.pendingConversationLaunch=null}})}dispose(){q$.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 B(`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 B(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),B(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return eZ(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${N(Z)}`;return B(`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)B(`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(..._Z(J.name,J.input));return Z}worktreeProjectName(){return Z2(this)}worktreeProjectDir(){return P4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return cW(this,$)}delegatedAgentDeveloperInstructions($){return uW(this,$)}worktreeInstructionLoadedNotice(){return NY(this)}withWorktreeInstructionNotice($){return lW(this,$)}worktreeExtraInstruction(){return o9(this)}runWorktreeCommand($,Z){return dW(this,$,Z)}showWorktrees(){return RY(this)}showTasklistPanel(){return OW(this)}showAgentIdentityPanel($=""){return jW(this,$)}onAgentIdentityPage($,Z,J){return LW($,Z,J)}onTasklistEnable(){return NW(this)}onTasklistDeletePrompt($){return RW(this,$)}onTasklistDeleteConfirm($){return TW(this,$)}runCompactCommand(){return tG(this)}showModelPanel(){return $W(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>WY(this,$,Z))}closeModelSettingsChanges(){this.modelSettingsChangesClosed=!0,this.modelSettingsChange?.cancel("daemon 正在停止")}modelSettingsBlockReason(){let $=this.modelSettingsChange;if(!$||$.proc!==this.proc||!$.proc.isAlive())return null;return $.phase==="pending"?"模型设置仍在等待后端确认,请等待结果;取消切换请发 kill 或 restart。":$.error??"模型设置未确认,请重新发送 md 选择模型。"}resumeInputAfterModelSettingsChange(){this.drainMidTurnAndOpen().catch(async($)=>{let Z=`模型设置已完成,但排队输入提交失败:${N($)}`;B(`session "${this.sessionName}": ${Z}`),await w(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Y=null){return this.runLifecycle("model-select",()=>XW(this,$,Z,J,Y))}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>jY(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return BY(this,$,Z)}onModelPage($,Z,J){return U7(this,$,Z,J)}onModelAddOpen($,Z){return ZW(this,$,Z)}onModelListEdit($,Z,J,Y){return this.runLifecycle("model-list-edit",()=>JW(this,$,Z,J,Y))}onModelPanelCancel($=""){return VW(this,$)}onModelCustomPrompt($,Z,J=""){return YW(this,$,Z,J)}consumeModelCustomMessage($,Z){return QW(this,$,Z)}onWorktreeDisband($){return nW(this,$)}showForkList($=""){return $K(this,$)}showBackList($=""){return ZK(this,$)}showResumeList($=""){return JK(this,$)}runBtwCommand($){return YK(this,$)}runByeCommand(){return QK(this)}onForkSelect($,Z,J=""){return VK(this,$,Z,J)}onBackSelect($,Z,J=""){return XK(this,$,Z,J)}onResumeSelect($,Z,J=""){return HK(this,$,Z,J)}runCommand($,Z="",J){return oG(this,$,Z,J)}getFileDeliveryMode(){return L4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return vW(this.chatId,this.sessionName,Z,$,{get:(J)=>L4.get(J,this.workDir),enable:(J,Y)=>L4.enable(J,this.workDir,Y),disable:(J)=>L4.disable(J,this.workDir),sendCard:(J)=>u(this.chatId,J),reportError:async(J)=>{if(B(`session "${this.sessionName}": ${J}`),!await E(this.chatId,J))throw Error(J)}},this.workDir)}async buildConsoleOpts($,Z){let J=await oX(),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:[...q$.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,accountUsages:xJ(),sysinfo:J}}async buildConsoleCard($){return D8(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await Ez()}catch(Y){let Q=N(Y);B(`console usage MISS: ${Q}`),Z.accountUsages=[{id:"error",label:"额度",usage:{state:"network",windows:[],reason:Q}}]}if(!await A0($,T.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,B(`session "${this.sessionName}": ${Z} mutation failed: ${N(V)}`)}let Q=!1;try{Q=await R0($,{config:{streaming_mode:!1}})}catch(V){B(`session "${this.sessionName}": ${Z} streaming-off failed: ${N(V)}`)}if(!Y||!Q)return B(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await H$($)}catch(V){return B(`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 G1($.cardId);let Q=await A0($.cardId,T.footer,q8(Y,T.footer)),V=await u1($.cardId,P8(Y),{type:"insert_after",targetElementId:T.footer}),X=await u1($.cardId,F8(Y.sysinfo),{type:"insert_after",targetElementId:T.consoleProjects}),H=await u1($.cardId,B9(Y),{type:"insert_after",targetElementId:T.consoleHost});if(!Q||!V||!X||!H){await w(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}v0($.cardId),await R0($.cardId,b1({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleOpts(void 0),Z=D8($),J=await u(this.chatId,Z);if(!J)return;if($.accountUsages!==void 0)return;(async()=>{let Y="";try{Y=await L$(J),X$(Y,4)}catch(Q){B(`session "${this.sessionName}": console card conversion failed: ${N(Q)}`);return}await this.mutateStaticCard(Y,"console usage",()=>this.patchConsoleUsage(Y))})().catch((Y)=>B(`session "${this.sessionName}": console async update rejected: ${N(Y)}`))}interrupt(){if(!this.proc)return;B(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}disabledSubscriptionMessage($=this.selectedTokenSourceId){let Z=this.tokenSource($);return Z?.kind==="claude-subscription"&&!Z.enabled?Z.modelCatalogState?.error??"Claude Code 订阅未启用,请发送 claude-sub 查看状态":null}async sendClaimedUserText($,Z){let J=this.modelSettingsBlockReason();if(J)throw Error(J);let Y=this.disabledSubscriptionMessage($.tokenSourceId);if(Y){let z=`❌ ${Y}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`;if(this.pendingTurnInputs=[],this.currentTurn)await this.closeTurnCard(z);else await E(this.chatId,z);return this.status="idle",!1}let Q=this.currentTurn,V=Q?Q.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),X=this.procFileDeliveryModes.get($),H=X===V?"":`${gW(V)}
246
+ ${QK($)}`}var DA;var fQ=O(()=>{DA=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});function z2($){return c8(c$($.sessionName)??$.sessionName)}function A4($){return r2(z2($))}function HK($){return r2($.sessionName)}function zK($,Z,J=$.currentProvider()){let Q=YK(J,Z),Y=Y3($);return Y?`${Q}
247
+ ${Y}`:Q}function WK($,Z){return Y3($)??""}function hQ($){return Y3($)?"已载入wt特殊约定":null}function GK($,Z){let J=hQ($);return J?`${Z}
248
+ ${J}`:Z}function Y3($){let Z=z2($),J=pH($.workDir,A4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
249
+ `)}async function KK($,Z,J){if(!Z){await IQ($);return}let Q=d1(Z);if(!Q){await S($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await S($.chatId,"❌ 找不到发起人,不能拉群。");return}let Y=z2($),V=A4($);try{await p8(V,async()=>{let X;try{X=uH(V,Y,Q)}catch(H){await S($.chatId,`❌ wt 失败: ${R(H)}`);return}try{let H=await LJ(X.chatName,J),z=H.created?"已创建":H.joined?"已加入":"已在群内";if(!await u($.chatId,O9({slug:Q,branch:X.branch,status:z})))await I($.chatId,`❌ wt 卡片失败: ${Q}`);if(!await u(H.chatId,O9({slug:Q,branch:X.branch,status:"就绪",body:"开始吧。"})))await I(H.chatId,`❌ wt 卡片失败: ${Q}`)}catch(H){await S($.chatId,`❌ wt 已建,拉群失败: ${R(H)}`)}})}catch(X){await S($.chatId,`❌ wt 失败: ${R(X)}`)}}async function BK($,Z){let J=z2($),Q=A4($);return await p8(Q,async()=>{return await UA(J,Q,Z)})}async function UA($,Z,J){let Q=cH(Z,$),Y=Q.filter((H)=>H.state==="merged"&&!H.mounted).length,V=Q.filter((H)=>H.state!=="merged"||H.mounted),X=await s8();return LZ({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Y,notice:J,entries:V.map((H)=>{let z=X.get(H.chatName)??[],W=K0.get(H.chatName),G=W&&z.includes(W)?W:z.length===1?z[0]:null;return{slug:H.slug,chatName:H.chatName,branch:H.branch,state:H.state,path:H.worktreePath??H.expectedPath,mounted:H.mounted,dirtyCount:H.dirtyCount,statusLine:H.statusLine,error:H.error,chatId:G,duplicateChatCount:z.length}})})}async function IQ($){try{let Z=await BK($);if(!await u($.chatId,Z))await I($.chatId,"❌ wt 列表失败")}catch(Z){await S($.chatId,`❌ wt 列表失败: ${R(Z)}`)}}async function XK($,Z,J,Q){try{return{ok:Z,message:J,card:await BK($,{type:Q,content:J})}}catch(Y){let V=`列表刷新失败: ${R(Y)}`;return B(`session "${$.sessionName}": wt action panel refresh failed: ${R(Y)}`),{ok:!1,message:`${J}
250
+ ${V}`,card:O9({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function _K($,Z){let J=d1(Z);if(!J)return XK($,!1,"❌ 名称无效","error");let Q=z2($),Y=A4($),V;try{V=await p8(Y,async()=>{let X=a2(Q,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};IZ(Y,Q,J);let H=await FJ(X),z=lH(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",H.disbanded?"group removed":"group missing",z.branch].join(`
251
+ `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${R(X)}`,type:"error"}}return XK($,V.ok,V.message,V.type)}var jK=O(()=>{fQ();H$();r();h();cZ()});import{closeSync as AA,openSync as OA,readSync as NA,readdirSync as RA,statSync as TA}from"node:fs";import{randomUUID as mQ}from"node:crypto";import{join as EA}from"node:path";function m5($){return c$($.sessionName)??$.sessionName}function qK($){let Z=WJ($,gQ);return gQ.add(Z),Z}function FK($){gQ.delete($)}function O4($){let Z=LK.get($);if(!Z)Z=new Map,LK.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let V=Y.status==="consumed"?CA:SA,X=Y.consumedAt??Y.createdAt;if(J-X>V)Z.delete(Q)}return Z}function kA($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function PK($,Z,J,Q){let Y={id:mQ(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:m5($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return O4($).set(Y.id,Y),Y}function pQ($,Z,J,Q,Y){let V=O4($).get(J);if(!V||V.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Y||V.requesterOpenId!==Y)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(V.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(V.provider!==$.selectedProvider||V.workDir!==$.workDir||V.sourceSessionId!==$.lastSessionId||!kA(V.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let X=V.choices.get(Q);if(!X)return{error:"无效的选择项,这张卡可能已过期"};return V.status="processing",{panel:V,choice:X}}function g5($){$.status="consumed",$.consumedAt=Date.now()}function wA($){return{kind:"fork",source:$.source,through:$}}function yA($){return $4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function vA($){let Z=Z4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return F0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function fA($){let Z=i3($),J;try{J=RA(Z)}catch(Y){if(Y?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Y?.message??Y}`)}let Q=[];for(let Y of J){if(!Y.endsWith(".jsonl"))continue;let V=Y.slice(0,-6);if(O2("claude",V))continue;let X=EA(Z,Y),H;try{H=TA(X).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${z?.message??z}`)}Q.push({provider:"claude",sessionId:V,cwd:$,preview:IA(X),ts:H})}return Q.sort((Y,V)=>V.ts-Y.ts)}function hA($){let Z=$.slice().sort((Y,V)=>V.ts-Y.ts),J=Date.now()-xA,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(bA,Math.max(10,Q)))}function IA($){let Z="",J=null;try{J=OA($,"r");let Y=Buffer.alloc(65536),V=NA(J,Y,0,65536,0);Z=Y.subarray(0,V).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)AA(J)}let Q="";for(let Y of Z.split(`
252
+ `)){let V=Y.trim();if(!V)continue;let X;try{X=JSON.parse(V)}catch{continue}if(X.type==="queue-operation"&&X.operation==="enqueue"&&typeof X.content==="string"){let H=X.content.trim();if(H)return H.slice(0,80)}if(!Q&&X.type==="user"&&X.message){let H=gA(X.message);if(H)Q=H}}return Q.slice(0,80)}function gA($){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 DK($,Z,J){if(!J){await S($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=yA($),Y=vA($),V=new Map,X=[];for(let G=0;G<Q.length;G++){let K=Q[G];if(G===0&&Y===null)continue;let _=mQ(),L=G===0?Y:wA(Q[G-1].checkpoint);V.set(_,{kind:Z,launch:L,branchBase:Y,seedAnchors:Q.slice(0,G),writes:Q.slice(G).flatMap((j)=>j.writes)}),X.push({choiceId:_,preview:K.preview,ts:K.ts})}X.reverse();let H=PK($,Z,J,V),z=FZ({projectName:m5($),panelId:H.id,mode:Z,entries:X}),W;try{W=await u($.chatId,z)}catch(G){throw O4($).delete(H.id),G}if(!W)O4($).delete(H.id),await I($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function UK($,Z){return DK($,"fork",Z)}function MK($,Z){return DK($,"back",Z)}async function AK($,Z){if(!Z){await S($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():fA($.workDir)}catch(z){await I($.chatId,`❌ 历史会话读取失败: ${z instanceof Error?z.message:z}`);return}let Q=new Map,Y=hA(J).map((z)=>{let W=mQ();return Q.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=PK($,"resume",Z,Q),X=PZ({projectName:m5($),panelId:V.id,entries:Y}),H;try{H=await u($.chatId,X)}catch(z){throw O4($).delete(V.id),z}if(!H)O4($).delete(V.id),await I($.chatId,"❌ rs 历史列表发送失败")}async function OK($,Z){if(!Z){await S($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await S($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=qK(m5($));await S($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Q;try{Q=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{FK(J)}if(!Q.ok){await S($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await S($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function NK($){if(!c$($.sessionName)){await S($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await S($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await S($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await S($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function RK($,Z,J,Q){let Y=pQ($,"fork",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let H=qK(V.baseName);B(`session-temp: fork ${$.sessionName} → ${H} (${X.launch.kind})`),await S($.chatId,`\uD83D\uDD31 正在分叉到 ${H}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:H,userOpenId:Q,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{FK(H)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${H};原会话和磁盘文件未回滚`}}catch(H){return{ok:!1,message:`分叉失败: ${H instanceof Error?H.message:H}`}}finally{g5(V)}}async function TK($,Z,J,Q){let Y=pQ($,"back",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let H="";try{if(!await u($.chatId,DZ({projectName:V.baseName,entries:X.writes})))H=";文件变更记录卡发送失败"}catch(G){H=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(B(`session-temp: back ${$.sessionName} (${X.launch.kind}, writes=${X.writes.length})`),!await $.rollbackTo(X.launch,{anchors:X.seedAnchors,base:X.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${H}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${H}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${O0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${H}`}}catch(H){return{ok:!1,message:`回退失败: ${H instanceof Error?H.message:H}`}}finally{g5(V)}}async function EK($,Z,J,Q){let Y=pQ($,"resume",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;if(X.kind!=="resume")throw g5(V),Error("resume panel contained a non-resume choice");let H=X.launch.source.sessionId,z=$.lastSessionId,W=(K,_)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:H,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:z,newSessionId:K,bindingState:_}),G=(K,_,L,j=null)=>({ok:K,message:_,resumePresentation:W(j,L)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(X.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(B(`session-temp: history fork ${$.sessionName} ← ${X.launch.source.provider} ${H}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:z}:null}))return G(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return G(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let _=$.lastSessionId;if(!_)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===H||z&&_===z)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return G(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(K){return G(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{g5(V)}}var xA=86400000,SA=1800000,CA=3600000,bA=40,LK,gQ;var xK=O(()=>{r();H$();h();f2();g4();C1();LK=new WeakMap,gQ=new Set});import{existsSync as SK}from"node:fs";import{randomBytes as cQ,timingSafeEqual as pA}from"node:crypto";import{isAbsolute as cA}from"node:path";function lQ($,Z=new Set){if($ instanceof b2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=lQ(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return lQ($.cause,Z);return null}function uA($){return $.itemId||$.turnId||"__latest__"}function CK($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function lA($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function dA($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function u5(){return g.runtime?.live_elapsed??"bucket"}function wK($,Z){return`${$} (${w2(Date.now()-Z,u5()).label})`}var bK="Thinking...",iA="Writing...",nA="Working...",uQ=1e4,p5=720000,aA=50,oA=256,c5=1e4,kK=250,D$;var xQ=O(()=>{g4();p4();G0();J1();W6();G0();S0();v6();EJ();e();f0();H4();f2();u$();H$();r();h();V0();XZ();T$();cz();mJ();pJ();ez();BW();EW();M5();CW();qG();PG();EG();IG();nG();$K();JK();fQ();jK();xK();C1();D$=class D${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=cQ(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;modelSettingsChange=null;modelSettingsChangesClosed=!1;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??Cz(),D$.all.add(this);let Q=KJ($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=I0(this.selectedTokenSourceId);if(Y){if(this.selectedProvider=Y.agent,Y.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Y.defaultModel,this.selectedEffort="max"}if(this.selectedModel)B(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=L1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=J4($);if(V)if(this.selectedProvider!=="claude")s0($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{F0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,H=this.lastSessionRef,z=!X&&H?.provider==="claude"&&H.cwd===this.workDir&&H.sessionId!==V.launch.source.sessionId&&H.sessionId!==V.previousSessionId;if(!X&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`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.currentTokenSource()?.codexApiProvider&&this.proc.codexAccountSelectionMode?.()!==null&&!(this.proc.turnRetry?.reason==="quota"&&this.proc.turnRetry.phase==="waiting")?{codexAccountName:y.get(v0(this.proc)).name}:{}}}get workDir(){return HK(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 N6(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?v0(this.proc):this.codexStartAccountOverride??y.selected(this.sessionName)}tokenSource($){let Z=I0($);return Z?.forAccount?H0($,this.codexAccountId()):Z}currentProvider(){return this.selectedProvider}conversationRouting(){let $=!!this.currentTokenSource()?.codexApiProvider;return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort,...$||this.codexAccountId()===p?{}:{codexAccountId:this.codexAccountId()},...!$&&y.preferred(this.sessionName)===null?{codexAccountAutomatic:!0}:{}}}applyConversationRouting($){if(this.isRunning()||this.currentTurn||this.openingTurn)throw Error("cannot change conversation routing while the session is running");let Z=I0($.tokenSourceId);if($.codexAccountId&&!Z?.codexApiProvider)y.get($.codexAccountId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)s0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;if(this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=L1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,F1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId),!Z?.codexApiProvider){let J=$.codexAccountId??p;if($.codexAccountAutomatic)y.selectAuto(this.sessionName);else if(y.selected(this.sessionName)!==J)y.select(this.sessionName,J)}}dshEffortForSpawn(){if(q0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&N$($,this.selectedModel??$.defaultModel);if(!Z||!q0(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 N2({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!O2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");let $=this.currentTokenSource();if(!$?.codexApiProvider&&!y9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(H)=>Z.spawnEnv(H):void 0,Q=new k2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J,...Z?.codexApiProvider?{apiProvider:Z.codexApiProvider}:{}}),Y=null,V=null;try{Y=await Q.listConversations()}catch(H){V=H}let X=null;try{await Q.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${R(V)}; ${R(X)}`);if(V)throw V;if(X)throw X;return Y??[]}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=n3(this.workDir,$.sessionId);if(!SK(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${O0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{let J=this.currentTokenSource();if(!J?.codexApiProvider&&!y9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Q=J?.enabled?J:void 0,Y=new k2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(H)=>Q.spawnEnv(H):void 0,...Q?.codexApiProvider?{apiProvider:Q.codexApiProvider}:{}}),V=null;try{Z=await Y.readConversationRef($.sessionId)}catch(H){V=H,Z=$}let X=null;try{await Y.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${R(V)}; cleanup=${R(X)}`);if(V)throw V;if(X)throw X}return F0({kind:"resume",source:Z},this.selectedProvider,this.workDir),C9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...D$.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 Z$(this.selectedEffort)?this.selectedEffort:s4}return s4}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&D0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=N$($,this.selectedModel??$.defaultModel);if(!D0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return e$}currentModelLabel(){if(this.modelSettingsChange?.proc===this.proc&&this.modelSettingsChange.phase==="failed")return this.modelSettingsChange.confirmedModel;return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){if(this.modelSettingsChange?.proc===this.proc&&this.modelSettingsChange.phase==="failed")return this.modelSettingsChange.confirmedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude")return this.selectedEffort??N$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?e$:s4)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider;if($&&this.modelSettingsChange?.proc===$&&this.modelSettingsChange.phase==="failed")return{provider:Z,model:this.modelSettingsChange.confirmedModel,effort:this.modelSettingsChange.confirmedEffort};let J=!$||$.provider===this.selectedProvider,Q=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Y=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?e$:s4);return{provider:Z,model:Q,effort:Y}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return Y0($,E.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:E.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return m6($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return y0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(F0($.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=cQ(32).toString("base64url");let Z={LODESTAR_AGENT_URL:Y8(g.notify.bind,g.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"});F0(J,this.selectedProvider,this.workDir);let Q=this.currentTokenSource(),Y=this.selectedProvider==="codex"&&this.selectedTokenSourceId==="codex-sub";if(this.selectedTokenSourceId&&(!Q||!Q.enabled&&!Y))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let V=Q?.enabled||Y?Q:void 0,X=this.currentTurn?.fileDeliveryMode??this.getFileDeliveryMode(),H=H9({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:V?.id??null,...this.selectedProvider==="codex"?{codexAccountId:y.selected(this.sessionName)}:{},...Y?{codexAccountPreference:this.codexStartAccountOverride??y.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(X),profile:x9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:L2},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),this.procFileDeliveryModes.set(H.process,X),H.process}async applyModelSelection($,Z,J,Q){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Q))}async applyModelSelectionUnlocked($,Z,J,Q){let Y=this.selectedProvider,V=Q??this.selectedTokenSourceId,X=I0(V),H=X?Z||null:$==="codex"?null:Z,z=X?J??N$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,H,z);let W=Y!==$?{anchors:$4(this.sessionName).slice(),base:Z4(this.sessionName),pending:J4(this.sessionName)}:null;if(W)s0(this.sessionName,[],null,null);try{F1(this.sessionName,$,H,z,V)}catch(G){if(W)try{s0(this.sessionName,W.anchors,W.base,W.pending)}catch(K){throw AggregateError([G,K],`model selection write failed: ${R(G)}; conversation state restore failed: ${R(K)}`)}throw G}if(W)this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=V,this.selectedModel=H,this.selectedEffort=z,this.lastSessionRef=L1(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null}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()===I2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===I2($,Z)}modelSelectionNeedsProcessStop($=this.selectedProvider,Z=this.selectedTokenSourceId,J=this.selectedModel,Q=this.selectedEffort){let Y=this.proc;return!!Y?.isAlive()&&(this.blockedProc===Y||Y.provider!==$||Y.tokenSourceId!==Z||$==="claude"&&Y.provider==="claude"&&Q!==null&&(Y.lastEffort??this.selectedEffort)==="default"!==(Q==="default")||!this.processSourceMatches(this.tokenSource(Z),J))}async stopIdleMismatchedProcessUnlocked($=this.selectedProvider,Z=this.selectedTokenSourceId,J=this.selectedModel,Q=this.selectedEffort){if(!this.proc||!this.modelSelectionNeedsProcessStop($,Z,J,Q))return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let Y=this.proc;B(`session "${this.sessionName}": stop idle ${Y.provider} process before switching to ${$}`),this.beginProcStop(Y),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let V=await this.settleProcResumableState(Y),X=null;try{await Y.kill()}catch(W){X=W}V=await this.settleProcResumableState(Y);let H=this.finishProcStop(Y,X);this.opts.onLifecycleChange?.();let z=[...X?[X]:!H?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...V?[Error(V)]:[]];if(z.length===1)throw z[0];if(z.length>1)throw AggregateError(z,`idle process stop failed: ${z.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;B(`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),Q=null;try{await Z.kill()}catch(X){Q=X}J=await this.settleProcResumableState(Z);let Y=this.finishProcStop(Z,Q);this.opts.onLifecycleChange?.();let V=[...Q?[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=(Q)=>Q){let Q=Date.now(),Y=Z,V=!1,X=()=>{if(V)return;this.replaceFooterContent($,J(wK(Y,Q)))},H=null,z=()=>{if(V)return;let{nextDelayMs:W}=w2(Date.now()-Q,u5());H=setTimeout(()=>{X(),z()},Math.max(1,Math.ceil(W)))};return X(),z(),{setStatus(W){Y=W,X()},stop(){if(V=!0,H)clearTimeout(H)},elapsedSec(){return(Date.now()-Q)/1000}}}async openStatusCard($,Z,J="blue"){let Q=Date.now(),Y=zZ({sessionName:this.sessionName,title:$,status:wK(Z,Q),template:J}),V=await u(this.chatId,Y);if(!V)return B(`session "${this.sessionName}": status card send failed title=${$}`),await I(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let X;try{X=await F$(V)}catch(H){return B(`session "${this.sessionName}": status card id_convert failed title=${$}: ${H}`),await I(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return W$(X,1),{cardId:X,title:$,timer:this.startFooterTimer(X,Z,(H)=>P9($,H))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=P9($.title,`${Z} (${U0(J)})`);await P1($.cardId);let Y=await A0($.cardId,E.footer,this.footerElement(Q));g0($.cardId);let V=await R0($.cardId,I1({durationSec:J,suffix:Z}));if(Y&&V)await G$($.cardId);else{let X=`footer=${Y?"ok":"MISS"}, settings=${V?"ok":"MISS"}`;B(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${X}`),await I(this.chatId,`⚠️ 状态卡片终态写入失败 (${X}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Q;this.lifecycleTail=new Promise((V)=>{Q=V}),await J;let Y=++this.lifecycleSequence;B(`session "${this.sessionName}": lifecycle#${Y} ${$} begin`);try{return await Z()}finally{Q(),B(`session "${this.sessionName}": lifecycle#${Y} ${$} 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 Q,Y=new Promise((X)=>{Q=X}),V={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Y,resolveDone:Q};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.modelSettingsChange?.cancel("原进程已更换"),this.modelSettingsChange=null,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.modelSettingsChange?.cancel("原进程已退出"),this.modelSettingsChange=null,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($){if(this.modelSettingsChange?.proc===$)this.modelSettingsChange.cancel("原进程正在停止"),this.modelSettingsChange=null;this.stoppingProc=$,this.agentCapability=null}acceptsAgentCapability($){let Z=this.agentCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Q=Buffer.from($);return J.length===Q.length&&pA(J,Q)}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",B(`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(Q){J=Q}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(V){Z=`Codex 会话落盘确认失败: ${R(V)}`}let Q=$.conversationMaterializationFailure?.();if(Q&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${R(Q)}`;let Y=this.persistResumableSessionId(!1,$,!1);return[Z,Y].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,s0(this.sessionName,[],{kind:"fresh"},null),this.currentGoal=null,this.cumStats={tokens:0,costUsd:0,turns:0},this.lastTurnDelta=null,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.lastTurnUsage=null,this.usageTotalsSeedUnknown=!1}async start($={}){return await this.runLifecycle("start",()=>this.startUnlocked($))}async startWithCodexAccount($,Z={}){return this.runLifecycle("hi-account",async()=>{if(y.get($),this.selectedProvider!=="codex"||this.currentTokenSource()?.codexApiProvider){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Q=H0("codex-sub",$)?.defaultModel||null;s0(this.sessionName,[],null,null),F1(this.sessionName,"codex",Q,null,"codex-sub"),this.pendingConversationMaterialization=null,this.selectedProvider="codex",this.selectedTokenSourceId="codex-sub",this.selectedModel=Q,this.selectedEffort=null,this.lastSessionRef=L1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")F1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&v0(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${y.get($).name}」`),!0;return this.proc?.isAlive()?await this.restartUnlocked(!0,Z):await this.startUnlocked(Z)}finally{this.codexStartAccountOverride=void 0}})}async startUnlocked($={}){let Z=$.announce??!0,J=$.onStatus,Q=this.blockedProcessMessage();if(Q){if(this.status="stopped",J?.(`❌ ${Q}`),Z)await S(this.chatId,`❌ ${Q}。请重试 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?.(this.currentTokenSource()?.codexApiProvider?"\uD83D\uDD0E 检查 Codex API 来源":"\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&this.selectedTokenSourceId!=="codex-sub"&&!this.currentTokenSource()?.codexApiProvider&&!y9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){if(!await u(this.chatId,P$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}return!1}if(!SK(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await S(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{AJ(this.workDir)}catch(G){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${G}`),Z)await S(this.chatId,`❌ 创建项目失败: ${G}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Y;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await w1();Y=this.spawnAgent()}catch(G){let K=`${this.backendLabel()} 启动失败: ${R(G)}`;if(B(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await S(this.chatId,`❌ ${K}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Y);let V=this.backendLabel(),X=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Y,kK):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let H,z=null;try{Y.sendInitialize(),H=Y.initializationPromise?.()}catch(G){H=void 0,z=G}let W=z?{state:"error",error:z}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(H),()=>{B(`session "${this.sessionName}": codex init still pending after ${uQ/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(W.state==="error"||W.state==="exit"){let G=W.error?R(W.error):W.state;B(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let _=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,L=`❌ ${V} 启动失败: ${G}${_}`;if(J?.(L),Z)await S(this.chatId,L);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="timeout"){B(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${p5/1000}s)`);let K=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${p5/1000} 秒内初始化事务未完成${K}`;if(J?.(_),Z)await S(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Y||!Y.isAlive()){let G=`${V} 启动期间已退出`;if(B(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await S(this.chatId,`❌ ${G}`);return this.detachProc(Y),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(W.state==="waiting_quota"){if(this.status="starting",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.("⏳ 账号额度用尽 · 自动等待恢复,可用后继续"),Z)await u(this.chatId,P$({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let G=this.modelLine();await S(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),G].filter(Boolean).join(`
253
+ `))}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 Q=!1,Y=(H,z)=>{if(Q)return;Q=!0,clearTimeout(V),clearTimeout(X),J({state:H,error:z})},V=setTimeout(()=>{if(Q)return;try{Z?.()}catch(H){Y("error",H)}},uQ),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${p5/1000}s`))},p5);$.then(()=>Y("init"),(H)=>Y("error",H)),this.proc?.quotaWaitPromise?.().then(()=>Y("waiting_quota"),(H)=>Y("error",H))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(W,G)=>{if(Q)return;Q=!0,clearTimeout(V),$.off("init",X),$.off("error",H),$.off("exit",z),J({state:W,error:G})},V=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),H=(W)=>Y("error",W),z=(W)=>Y("exit",W);$.once("init",X),$.once("error",H),$.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;B(`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,Q=Z.onStatus;if(this.daemonRestoreRequired=!1,await this.cancelAgentRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.("⚪ session 当前未运行"),J)await S(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Y=this.proc,V=this.persistResumableSessionId(!1,Y,!1),X=null;if(Q?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),B(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((P)=>{B(`session "${this.sessionName}": stop current main-card close failed: ${R(P)}`)});let H=this.waitForTurnCloses().catch((P)=>B(`session "${this.sessionName}": stop main-card close failed: ${R(P)}`));this.beginProcStop(Y),this.status="stopped";let z=[];try{this.opts.onLifecycleChange?.()}catch(P){z.push(P),B(`session "${this.sessionName}": stop intent lifecycle write failed: ${R(P)}`)}let W=Y.conversationMaterializationBarrier?.();if(W){try{await W}catch(P){X=`Codex 会话落盘确认失败: ${R(P)}`}V=this.persistResumableSessionId(!1,Y,!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 Y.kill()}catch(P){G=P}let K=Y.conversationMaterializationFailure?.();if(K&&Y.isConversationResumable?.()!==!0)X=`Codex 会话落盘确认失败: ${R(K)}`;V=this.persistResumableSessionId(!1,Y,!1);let L=(await Promise.allSettled([this.resetBackgroundTasks(),H])).filter((P)=>P.status==="rejected").map((P)=>P.reason);for(let P of L)B(`session "${this.sessionName}": stop terminal cleanup failed: ${R(P)}`);let j=this.finishProcStop(Y,G);try{this.opts.onLifecycleChange?.()}catch(P){z.push(P),B(`session "${this.sessionName}": stop final lifecycle write failed: ${R(P)}`)}let q=[...G?[G]:[],...!j&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...L,...z,...V?[Error(V)]:[],...X&&Y.isConversationResumable?.()!==!0?[Error(X)]:[]];if(q.length===1)throw q[0];if(q.length>1)throw AggregateError(q,`stop failed: ${q.map(R).join("; ")}`);if(Q?.(`✅ ${$}`),J)await S(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 S(this.chatId,"❌ daemon 重启后没有可用的恢复点。请发送 rs 选择历史会话,或 hi 明确启动新会话。"),!1;return await this.restartUnlocked(!0)})}async restartUnlocked($=!1,Z={},J){let Q=Z.announce??!0,Y=Z.onStatus,V=this.status,X=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)X=this.pendingConversationMaterialization,q1(this.sessionName,null),this.pendingConversationMaterialization=null;let H=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!H&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(C){let f=this.invalidateMissingCodexResume(z.sessionId,C,J),m=f?`❌ 旧会话不可恢复: ${R(C)};${f}`:`❌ 旧会话 cwd 校验失败: ${R(C)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Y?.(m),Q)await S(this.chatId,m);return!1}let W=z?.sessionId??null,G=H&&H.kind!=="fresh"?H.source.sessionId:W,K=G?O0(G):"",_=null,L=(C=this.proc)=>{if(!$||H||C?.provider!=="codex"||C.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,C,!1),z=this.lastSessionRef,W=z?.sessionId??null,G=W,K=G?O0(G):""},j=null;if(!Y&&Q&&$&&W){let C=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(j=await this.openStatusCard("restart",C),j)Y=(f)=>this.setStatusCard(j,f)}let q=Q&&!j,P=async(C)=>{if(j)await this.closeStatusCard(j,C)},N=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||Z6(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let C of this.fileDeliveries)C.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((C)=>{B(`session "${this.sessionName}": restart current main-card close failed: ${R(C)}`)});let D=this.waitForTurnCloses().catch((C)=>B(`session "${this.sessionName}": restart main-card close failed: ${R(C)}`)),U=null,M=null;if(this.proc){let C=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(C.provider)}`),M=C,this.beginProcStop(C);let f=C.conversationMaterializationBarrier?.();if(f)try{await f}catch(l){_=`Codex 会话落盘确认失败: ${R(l)}`}if(L(C),$&&!H&&_&&!N&&C.isAlive()){if(this.stoppingProc===C)this.stoppingProc=null;this.status=V;let l=`❌ ${this.backendLabel(C.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(B(`session "${this.sessionName}": abort restart before kill: ${_}`),Y?.(l),q)await S(this.chatId,l);return await P(l),!1}try{await C.kill()}catch(l){U=l}let m=C.conversationMaterializationFailure?.();if(m&&C.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${R(m)}`;L(C)}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 x=(await Promise.allSettled([this.resetBackgroundTasks(),D])).filter((C)=>C.status==="rejected").map((C)=>C.reason);for(let C of x)B(`session "${this.sessionName}": restart terminal cleanup failed: ${R(C)}`);let w=M?this.finishProcStop(M,U):!0,b=[...U?[`kill=${R(U)}`]:[],...!w&&!U?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...x.map((C)=>`cleanup=${R(C)}`),..._?[`resume=${_}`]:[]];if(b.length>0&&X)try{q1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(C){b.push(`pendingRestore=${R(C)}`)}if(b.length>0){let C=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${b.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(C),q)await S(this.chatId,C);return await P(C),!1}let v=H?.kind==="resume"||H?.kind==="fork";if($&&z||v){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let C;try{if(this.selectedProvider!=="codex"||!this.codexStartAccountOverride&&y.preferred(this.sessionName)===null)await w1();C=this.spawnAgent(z??void 0)}catch(a){let L0=`❌ ${this.backendLabel()} 恢复失败: ${R(a)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${R(a)}`),Y?.(L0),q)await S(this.chatId,L0);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(L0),!1}this.attachProc(C);let f=this.backendLabel(),m=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(C,kK):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${f} 恢复启动`:`⏳ 等待 ${f} init 确认`);let l,A=null;try{C.sendInitialize(),l=C.initializationPromise?.()}catch(a){l=void 0,A=a}let k=A?{state:"error",error:A}:this.selectedProvider==="claude"?await m:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(l),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${uQ/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${f} init 确认 thread=${K}`))});if(k.state==="error"||k.state==="exit"||k.state==="timeout"){let a=k.state==="error"?this.invalidateMissingCodexResume(G,k.error,J):null,L0=[k.error?R(k.error):k.state,a].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${L0}`);let W3=await this.stopOwnedProc(C,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B2=k.state==="timeout"?`❌ ${f} 恢复超时${W3}`:`❌ ${f} 恢复失败: ${L0}${W3}`;if(Y?.(B2),q)await S(this.chatId,B2);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(B2),!1}if(this.proc!==C||!C.isAlive()){let a=`❌ ${f} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(a),q)await S(this.chatId,a);return this.detachProc(C),this.status="stopped",this.opts.onLifecycleChange?.(),await P(a),!1}let d=this.withModel(this.withWorktreeInstructionNotice(k.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&k.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Y?.(d),q)await S(this.chatId,d);if(this.status=k.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),k.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await P(d)}catch(a){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${R(a)}`),await I(this.chatId,`⚠️ ${d}
254
+ 状态卡收尾失败: ${R(a)}`)}return!0}else{if($&&!H){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),q)await S(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{F0($,this.selectedProvider,this.workDir);let J=J4(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)q1(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)q1(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{q1(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Y,V],`fork start and pending-intent restore failed: ${R(Y)}; ${R(V)}`)}throw Y}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{F0($,this.selectedProvider,this.workDir);let Q=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,Y=this.proc,V=this.lastSessionId,X=this.lastSessionRef,H=$4(this.sessionName).slice(),z=Z4(this.sessionName),W=J4(this.sessionName),G={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,_=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,e2(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)C9(this.sessionName,X);else e2(this.sessionName,this.selectedProvider);s0(this.sessionName,H,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},L=!1;if(Q?.pendingLaunch)s0(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,L=!0;this.pendingConversationLaunch=$;let j=(q)=>{K=X?.provider==="codex"&&X.sessionId===q};try{let q;try{q=$.kind==="fresh"?await this.restartUnlocked(!1,J,j):await this.restartUnlocked(!0,J,j)}catch(P){let N=null,D=this.proc&&this.proc!==Y?this.proc:null;if(D)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(x){N=x}let U=!D||this.proc!==D&&!D.isAlive();if(!U&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(U)try{_()}catch(x){M=x}let T=[P,...N?[N]:[],...M?[M]:[]];if(T.length===1)throw P;throw AggregateError(T,`rollback launch and cleanup failed: ${T.map(R).join("; ")}`)}if(!q)return _(),!1;if(Q)try{if(!L)s0(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(P){let N=null,D=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(x){N=x}let U=!D||this.proc!==D&&!D.isAlive();if(!U&&!N)N=Error("replacement process stop was not confirmed");let M=null;if(U)try{_()}catch(x){M=x}let T=[P,...N?[N]:[],...M?[M]:[]];if(T.length===1)throw P;throw AggregateError(T,`rollback branch commit failed: ${T.map(R).join("; ")}`)}return q}finally{this.pendingConversationLaunch=null}})}dispose(){D$.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 Q=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return B(`session "${this.sessionName}": ${Q}`),this.lastTurnUserPreview="",Q}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((Y)=>Y.proc===Z).length>=64)return B(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),B(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return zJ(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${R(Z)}`;return B(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Q of this.pendingCodexTurnAnchors){if(Q.proc!==$||Z){J.push(Q);continue}if(Z=this.appendTurnAnchor(Q.anchor),Z)J.push(Q)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Y)=>Y.proc!==$);let Q=J-this.pendingCodexTurnAnchors.length;if(Q>0)B(`session "${this.sessionName}": dropped ${Q} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...AZ(J.name,J.input));return Z}worktreeProjectName(){return z2(this)}worktreeProjectDir(){return A4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return zK(this,$)}delegatedAgentDeveloperInstructions($){return WK(this,$)}worktreeInstructionLoadedNotice(){return hQ(this)}withWorktreeInstructionNotice($){return GK(this,$)}worktreeExtraInstruction(){return Y3(this)}runWorktreeCommand($,Z){return KK(this,$,Z)}showWorktrees(){return IQ(this)}showTasklistPanel(){return uG(this)}showAgentIdentityPanel($=""){return yG(this,$)}onAgentIdentityPage($,Z,J){return vG($,Z,J)}onTasklistEnable(){return lG(this)}onTasklistDeletePrompt($){return dG(this,$)}onTasklistDeleteConfirm($){return iG(this,$)}runCompactCommand(){return FG(this)}showModelPanel(){return UG(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>OQ(this,$,Z))}closeModelSettingsChanges(){this.modelSettingsChangesClosed=!0,this.modelSettingsChange?.cancel("daemon 正在停止")}modelSettingsBlockReason(){let $=this.modelSettingsChange;if(!$||$.proc!==this.proc||!$.proc.isAlive())return null;return $.phase==="pending"?"模型设置仍在等待后端确认,请等待结果;取消切换请发 kill 或 restart。":$.error??"模型设置未确认,请重新发送 md 选择模型。"}resumeInputAfterModelSettingsChange(){this.drainMidTurnAndOpen().catch(async($)=>{let Z=`模型设置已完成,但排队输入提交失败:${R($)}`;B(`session "${this.sessionName}": ${Z}`),await I(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Q=null){return this.runLifecycle("model-select",()=>TG(this,$,Z,J,Q))}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>EQ(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return RQ(this,$,Z)}onModelPage($,Z,J){return k5(this,$,Z,J)}onModelAddOpen($,Z){return MG(this,$,Z)}onModelListEdit($,Z,J,Q){return this.runLifecycle("model-list-edit",()=>AG(this,$,Z,J,Q))}onModelPanelCancel($=""){return RG(this,$)}onModelCustomPrompt($,Z,J=""){return OG(this,$,Z,J)}consumeModelCustomMessage($,Z){return NG(this,$,Z)}onWorktreeDisband($){return _K(this,$)}showForkList($=""){return UK(this,$)}showBackList($=""){return MK(this,$)}showResumeList($=""){return AK(this,$)}runBtwCommand($){return OK(this,$)}runByeCommand(){return NK(this)}onForkSelect($,Z,J=""){return RK(this,$,Z,J)}onBackSelect($,Z,J=""){return TK(this,$,Z,J)}onResumeSelect($,Z,J=""){return EK(this,$,Z,J)}runCommand($,Z="",J){return LG(this,$,Z,J)}getFileDeliveryMode(){return M4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return ZK(this.chatId,this.sessionName,Z,$,{get:(J)=>M4.get(J,this.workDir),enable:(J,Q)=>M4.enable(J,this.workDir,Q),disable:(J)=>M4.disable(J,this.workDir),sendCard:(J)=>u(this.chatId,J),reportError:async(J)=>{if(B(`session "${this.sessionName}": ${J}`),!await S(this.chatId,J))throw Error(J)}},this.workDir)}async buildConsoleOpts($,Z){let J=await zH(),Q=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Q.provider,model:Q.model??void 0,effort:Q.effort??"MISS",worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...D$.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,accountUsages:gJ(),sysinfo:J}}async buildConsoleCard($){return x8(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await pz()}catch(Q){let Y=R(Q);B(`console usage MISS: ${Y}`),Z.accountUsages=[{id:"error",label:"额度",usage:{state:"network",windows:[],reason:Y}}]}if(!await A0($,E.consoleUsage,D9(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Q=!0;try{await J()}catch(V){Q=!1,B(`session "${this.sessionName}": ${Z} mutation failed: ${R(V)}`)}let Y=!1;try{Y=await R0($,{config:{streaming_mode:!1}})}catch(V){B(`session "${this.sessionName}": ${Z} streaming-off failed: ${R(V)}`)}if(!Q||!Y)return B(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Q} streamingOff=${Y} card=${$.slice(0,12)}`),!1;try{await G$($)}catch(V){return B(`session "${this.sessionName}": ${Z} dispose failed: ${R(V)}`),!1}return Q}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Q=await this.buildConsoleOpts(void 0);await P1($.cardId);let Y=await A0($.cardId,E.footer,T8(Q,E.footer)),V=await s1($.cardId,R8(Q),{type:"insert_after",targetElementId:E.footer}),X=await s1($.cardId,E8(Q.sysinfo),{type:"insert_after",targetElementId:E.consoleProjects}),H=await s1($.cardId,D9(Q),{type:"insert_after",targetElementId:E.consoleHost});if(!Y||!V||!X||!H){await I(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}g0($.cardId),await R0($.cardId,I1({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleOpts(void 0),Z=x8($),J=await u(this.chatId,Z);if(!J)return;if($.accountUsages!==void 0)return;(async()=>{let Q="";try{Q=await F$(J),W$(Q,4)}catch(Y){B(`session "${this.sessionName}": console card conversion failed: ${R(Y)}`);return}await this.mutateStaticCard(Q,"console usage",()=>this.patchConsoleUsage(Q))})().catch((Q)=>B(`session "${this.sessionName}": console async update rejected: ${R(Q)}`))}interrupt(){if(!this.proc)return;B(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}disabledSubscriptionMessage($=this.selectedTokenSourceId){let Z=this.tokenSource($);return Z?.kind==="claude-subscription"&&!Z.enabled?Z.modelCatalogState?.error??"Claude Code 订阅未启用,请发送 claude-sub 查看状态":null}async sendClaimedUserText($,Z){let J=this.modelSettingsBlockReason();if(J)throw Error(J);let Q=this.disabledSubscriptionMessage($.tokenSourceId);if(Q){let z=`❌ ${Q}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`;if(this.pendingTurnInputs=[],this.currentTurn)await this.closeTurnCard(z);else await S(this.chatId,z);return this.status="idle",!1}let Y=this.currentTurn,V=Y?Y.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),X=this.procFileDeliveryModes.get($),H=X===V?"":`${VK(V)}
254
255
 
255
- `;this.procFileDeliveryModes.set($,V),this.pendingUserMessageCount++;try{$.sendUserText(H+Z,[])}catch(z){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),X===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,X);throw z}return!0}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 X=this.startFooterTimer(V.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(W)=>this.withModel(W)),H=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(W)=>{H=W,X.setStatus(W)}});if(X.stop(),await G1(V.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(H.startsWith("❌")?H:"❌ 启动失败",{forcePush:!0});return}let G=this.proc;if(!G?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}if(this.startThinkingFooter(V),!await this.sendClaimedUserText(G,Z))return;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.modelSettingsBlockReason();if(Q){await E(this.chatId,`⚠️ ${Q} 本条消息未送给 Agent,请确认设置后重发。`);return}let V=this.disabledSubscriptionMessage();if(V){await E(this.chatId,`❌ ${V}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`);return}let X=this.blockedProcessMessage();if(X){await E(this.chatId,`❌ ${X}。请重试 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 H=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let G=(Z.length?Z.map((K)=>`[file: ${K}]`).join(" ")+`
256
- `:"")+$,W=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let _=await d0(K,"OneSecond");if(!_)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,_);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,_);else k0(K,_)})().catch((_)=>{B(`session "${this.sessionName}": reaction tracking failed: ${N(_)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Y}),Y)W(Y);return}await this.startColdUserTurn($,G,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Y}),Y)W(Y);return}if(!this.openingTurn&&this.initCount>=1){let K=this.proc,_=this.procEpoch,L=this.beginTurnOpen(K,_);try{this.pendingTurnInputs.push($);let j=await this.openTurnCard(L,J,"user_message");if(!j||this.currentTurn!==j)return;if(this.proc!==K||this.procEpoch!==_||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,G))return;this.status="working"}finally{this.releaseTurnOpen(L)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Y}),Y)W(Y);return}if(this.pendingTurnInputs.push($),!await this.sendClaimedUserText(this.proc,G))return;if(H&&Y)W(Y)}hasPendingAsk(){return XG(this)}refreshPendingAsks(){G7(this)}askBlockReason($){return G4(this,$)}onMultiMessageInbound($,Z,J,Y){return Iz(this,$,Z,J,Y)}clearMultiMsgBuffer($){kJ(this,$)}onAskMessageAnswer($,Z,J){return HG(this,$,Z,J)}onAskAnswer($,Z,J,Y){return zG(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return uJ(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return jG(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=X1(this.sessionName,"codex");if(a2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)B(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=bY(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=X1(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{a2(this.sessionName,"codex")}catch(X){let H=`已确认恢复点无 rollout,但作废失败: ${N(X)}`;return B(`session "${this.sessionName}": ${H} thread=${$}`),H}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${O0($)}`;return B(`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 H=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.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 H=Error(`Claude fork did not materialize an independent session id (${Q})`);if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}try{O9(this.sessionName,V)}catch(H){let z=`会话恢复点持久化失败: ${N(H)}`,G=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;if(B(`session "${this.sessionName}": ${z}`),$)throw H;if(G&&J)w(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Q;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let H=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(H&&J)w(this.chatId,`⚠️ ${X}`);return X}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 B(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return H1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${N(J)}`;return B(`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(o5(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(B(`session "${this.sessionName}": delegation panel update failed: ${Z}`),this.backgroundWriteError===Z)return;this.backgroundWriteError=Z,await w(this.chatId,`⚠️ 委派面板更新失败:${Z}`)}async resetBackgroundTasks(){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null;let $=Date.now();if(this.backgroundTasks=this.backgroundTasks.map((Z)=>G$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$}),this.pendingBgTasks=[],this.backgroundSync)try{await this.backgroundSync}catch(Z){B(`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=SY(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(X){B(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${N(X)}`);return}let V=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${V.slice(0,78)}`,B(`session "${this.sessionName}": scheduled wakeup prompt=${Y??"MISS"}`),(async()=>{try{let X=await this.openTurnCard(Q,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(B(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),X&&this.currentTurn===X)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!X||this.currentTurn!==X){if(!this.ownsTurnOpen(Q))return;if(this.bgResumeCardless=!0,Q.sawResult)Q.sawResult=!1,B(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else B(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,B(`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((X)=>{B(`session "${this.sessionName}": scheduled turn-open handler failed: ${N(X)}`)})}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,X=(H,z)=>{$.on(H,(G)=>{if(!Y()){if(!Q)Q=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(H)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(H!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(H)} while process stop is pending`);return}z(G)})};X("error",(H)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${H}`)}),X("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++,B(`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)B(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let H=this.pendingUserMessageCount>0,z=!H&&this.bgResumePending;if(!H&&!z)return;let G=this.lastUserOpenId,W;try{W=this.beginTurnOpen($,J,!0)}catch(L){B(`session "${this.sessionName}": init turn-open ownership conflict: ${N(L)}`);return}if(this.bgResumePending=!1,H)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=H?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let L of K){let j=this.currentBatchReactionIds.get(L);if(this.currentBatchReactionIds.delete(L),j)k0(L,j)}};(async()=>{try{let L=await this.openTurnCard(W,G,H?"user_message":"bg_task_resume");if(!Y()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),L&&this.currentTurn===L)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!L||this.currentTurn!==L){if(!this.ownsTurnOpen(W)){_();return}if(W.sawResult&&W.terminalSuffix)w(this.chatId,W.terminalSuffix);if(H)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else B(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(W.terminalSuffix,{forcePush:W.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(W)}})().catch((L)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${N(L)}`)})}),X("scheduled_turn_input",({text:H,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,H,z)}),X("conversation_materialized",({session_id:H,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==H){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${H} current=${$.sessionId??"MISS"} source=${z}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${H} source=${z}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:H,source:z,error:G})=>{if($.provider!=="codex"||$.sessionId!==H)return;let W=`Codex 会话落盘确认失败,未写恢复点: ${N(G)}`,K=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,B(`session "${this.sessionName}": ${W} thread=${H} source=${z}`),K)w(this.chatId,`⚠️ ${W}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:H,diagnostics:z})=>{if(B(`session "${this.sessionName}": Codex account=${H}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)u(this.chatId,P$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
257
- `),hint:"详情:codex-accounts"})).catch((G)=>{B(`session "${this.sessionName}": 账号诊断卡失败: ${N(G)}`)})}),X("turn_started",({retry:H})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)B(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),H){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}),X("token_usage",({totalUsage:H})=>{if(this.persistResumableSessionId(),H)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(H)=>{this.handleTurnPlanUpdated(H)}),X("plan_delta",(H)=>{this.handlePlanDelta(H)}),X("context_compacted",(H)=>{this.handleContextCompacted(H)}),X("rate_limits_updated",(H)=>{if($.provider==="codex")JX(H,y0($))}),X("thread_goal_updated",(H)=>{this.handleThreadGoalUpdated(H)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:H,parentToolUseId:z})=>{if(z)return;this.appendAssistant(H)}),X("assistant_block_stop",({parentToolUseId:H})=>{if(H)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:H,name:z,input:G,parentToolUseId:W})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(s5({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}if(!W&&(z==="Task"||z==="Agent"||$.provider==="dsh"&&(z==="subagent"||z==="subagent_fork"))){let K=this.currentTurn;if(K)this.startWorkingFooter(K),this.finalizeCurrentAssistantSegment(),K.openBatchI=null,K.taskCreateI=null,K.taskUpdateI=null;if(this.onMainThreadAdvance(),this.nativeAgentTools.set(H,{confirmed:!1,input:G}),$.provider==="claude")this.lastMainTaskToolUseId=H,this.applyBgStore(d4(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:G?.description||G?.name||"子 Agent",prompt:G?.prompt,subagent_type:G?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(KG(this,H,z,G),!W)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:H,content:z,is_error:G,parentToolUseId:W,input:K})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(r5({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}let _=!W&&this.nativeAgentTools.get(H);if(_){if(this.nativeAgentTools.delete(H),this.lastMainTaskToolUseId===H)this.lastMainTaskToolUseId=null;if(G||$.provider==="claude"&&!_.confirmed&&_.input?.run_in_background!==!0){let L=typeof z==="string"?z:Array.isArray(z)?z.map((q)=>typeof q?.text==="string"?q.text:JSON.stringify(q)).join(`
258
- `):JSON.stringify(z)??"MISS",j=this.backgroundTasks.find((q)=>q.toolUseId===H);if(!j)this.applyBgStore(d4(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:_.input?.description||"子 Agent",prompt:_.input?.prompt})),j=this.backgroundTasks.find((q)=>q.toolUseId===H);this.applyBgStore(b3(this.bgStore(),{task_id:j.id,status:G?"failed":"completed",summary:L})),this.onBackgroundTaskChanged(!0)}a1(this);return}BG(this,H,z,G,K)}),X("can_use_tool",(H)=>{LG(this,H)}),X("hook_callback",(H)=>{this.proc?.sendHookResponse(H.request_id,{})}),X("result",(H)=>{let z=this.persistResumableSessionId(),G=z?null:this.consumePendingConversationMaterialization(),W=[z,G].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 A=this.proc?.lastResult.subtype??"unknown",x=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${A} isError=${x} — ignored`),this.status="idle";return}let K=H?.is_error!==!0?this.recordTurnAnchor(H?.checkpoint):null;if(H?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,L=this.proc?.lastResult.is_error===!0,j=this.proc?.lastResult.subtype??"success",q=typeof H?.error==="string"&&H.error.trim()?H.error.trim():j,F,R=!1,D=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),U=[W,K].filter(Boolean).join(";")||null;if(U)F=`⚠️ ${U}`,R=!0;else if(_)F=L?`⚠️ ${D} ${q},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(L)F=`⚠️ ${D} ${q}`,R=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=F,this.openingTurnOwner.terminalForcePush=R;if(U&&!this.currentTurn&&!this.openingTurn)w(this.chatId,`⚠️ ${U}`);if(B(`session "${this.sessionName}": SDK result subtype=${j} isError=${L} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${R}`),this.closeTurnCard(F,{forcePush:R,hasFreshResult:!0}).catch((A)=>{B(`session "${this.sessionName}": result card close failed: ${N(A)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((A)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${N(A)}`)})}),X("bg_task_started",(H)=>{let z=H.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,G=z?this.nativeAgentTools.get(z):void 0;if(G)G.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${H.task_id} type=${H.task_type??"-"} subagent=${H.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(H.description??"").slice(0,40)}`),this.applyBgStore(d4(this.bgStore(),{...H,tool_use_id:z})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(H)=>{this.applyBgStore(n5(this.bgStore(),H)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(H)=>{this.applyBgStore(a5(this.bgStore(),H)),this.onBackgroundTaskChanged(!!H.patch.status||H.patch.is_backgrounded===!0)}),X("bg_task_settled",(H)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${H.task_id} status=${H.status}`),this.applyBgStore(b3(this.bgStore(),H)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(H)=>{this.applyBgStore(t5(this.bgStore(),H.thread_id,H.item_id,H.tool,H.phase,H.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:H,signal:z,expected:G})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${H} signal=${z} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let j=$.conversationMaterializationFailure?.(),q=this.persistResumableSessionId(!1,$,!1),F=[j&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${N(j)}`:null,q].filter(Boolean).join(";");if(F)w(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${F}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}B(`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((j)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${N(j)}`)});let W=this.backendLabel($.provider),K=`code=${H??"null"}, signal=${z??"null"}`,_=G?`\uD83D\uDED1 ${W} 已退出`:`⚠️ ${W} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(_).catch((j)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${N(j)}`)});let L=this.waitForTurnCloses().catch((j)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${N(j)}`)});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 j=await Promise.allSettled([L,this.resetBackgroundTasks()]);for(let q of j)if(q.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${N(q.reason)}`);if(!G)await E(this.chatId,`⚠️ ${W} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((j)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${N(j)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?S5(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=C5(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 t3(Z)}contextLimitForDisplay($=this.proc){return r3($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;if(this.modelSettingsBlockReason())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||this.modelSettingsBlockReason())return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){B(`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 G=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,G),this.pendingReactionIds.delete(z.msgId)}let Q=Y.map((z)=>z.wireText).join(`
256
+ `;this.procFileDeliveryModes.set($,V),this.pendingUserMessageCount++;try{$.sendUserText(H+Z,[])}catch(z){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),X===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,X);throw z}return!0}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Q=this.beginTurnOpen();try{let V=await this.openTurnCard(Q,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!V||this.currentTurn!==V)return;let X=this.startFooterTimer(V.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),H=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{H=G,X.setStatus(G)}});if(X.stop(),await P1(V.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(H.startsWith("❌")?H:"❌ 启动失败",{forcePush:!0});return}let W=this.proc;if(!W?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}if(this.startThinkingFooter(V),!await this.sendClaimedUserText(W,Z))return;this.status="working"}finally{this.releaseTurnOpen(Q)}}async onUserMessage($,Z=[],J="",Q=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Q))}async onUserMessageUnlocked($,Z,J,Q){let Y=this.modelSettingsBlockReason();if(Y){await S(this.chatId,`⚠️ ${Y} 本条消息未送给 Agent,请确认设置后重发。`);return}let V=this.disabledSubscriptionMessage();if(V){await S(this.chatId,`❌ ${V}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`);return}let X=this.blockedProcessMessage();if(X){await S(this.chatId,`❌ ${X}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await S(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 H=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let W=(Z.length?Z.map((K)=>`[file: ${K}]`).join(" ")+`
257
+ `:"")+$,G=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let _=await t0(K,"OneSecond");if(!_)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,_);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,_);else k0(K,_)})().catch((_)=>{B(`session "${this.sessionName}": reaction tracking failed: ${R(_)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:W,userOpenId:J,msgId:Q}),Q)G(Q);return}await this.startColdUserTurn($,W,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:W,userOpenId:J,msgId:Q}),Q)G(Q);return}if(!this.openingTurn&&this.initCount>=1){let K=this.proc,_=this.procEpoch,L=this.beginTurnOpen(K,_);try{this.pendingTurnInputs.push($);let j=await this.openTurnCard(L,J,"user_message");if(!j||this.currentTurn!==j)return;if(this.proc!==K||this.procEpoch!==_||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,W))return;this.status="working"}finally{this.releaseTurnOpen(L)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:W,userOpenId:J,msgId:Q}),Q)G(Q);return}if(this.pendingTurnInputs.push($),!await this.sendClaimedUserText(this.proc,W))return;if(H&&Q)G(Q)}hasPendingAsk(){return UW(this)}refreshPendingAsks(){U5(this)}askBlockReason($){return L4(this,$)}onMultiMessageInbound($,Z,J,Q){return rz(this,$,Z,J,Q)}clearMultiMsgBuffer($){uJ(this,$)}onAskMessageAnswer($,Z,J){return MW(this,$,Z,J)}onAskAnswer($,Z,J,Q){return AW(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return $Q(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return xW(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=L1(this.sessionName,"codex");if(e2(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)B(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Q=lQ(Z);if(!Q||!["thread/read","thread/resume","thread/fork"].includes(Q.method)||Q.serverCode!==-32600||Q.serverMessage!==`no rollout found for thread id ${$}`)return null;let Y=L1(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{e2(this.sessionName,"codex")}catch(X){let H=`已确认恢复点无 rollout,但作废失败: ${R(X)}`;return B(`session "${this.sessionName}": ${H} thread=${$}`),H}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${O0($)}`;return B(`session "${this.sessionName}": ${V} fullThread=${$}`),V}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Q=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Y=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Y){if(!Q)return null;let H=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}let V={provider:Z.provider,sessionId:Y,cwd:this.workDir};if(Q&&(Y===Q.launch.source.sessionId||Q.previousSessionId!==null&&Y===Q.previousSessionId)){let H=Error(`Claude fork did not materialize an independent session id (${Y})`);if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}try{C9(this.sessionName,V)}catch(H){let z=`会话恢复点持久化失败: ${R(H)}`,W=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;if(B(`session "${this.sessionName}": ${z}`),$)throw H;if(W&&J)I(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let H=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(H&&J)I(this.chatId,`⚠️ ${X}`);return X}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 B(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return q1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Q=`Claude 待生成分支标记清除失败: ${R(J)}`;return B(`session "${this.sessionName}": ${Q}`),Q}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(Y6(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),Q;return Q=J.then(()=>{this.backgroundWriteError=null}).finally(()=>{if(this.backgroundSync===Q)this.backgroundSync=null}),this.backgroundSync=Q,Q}async reportBackgroundWriteFailure($){let Z=R($);if(B(`session "${this.sessionName}": delegation panel update failed: ${Z}`),this.backgroundWriteError===Z)return;this.backgroundWriteError=Z,await I(this.chatId,`⚠️ 委派面板更新失败:${Z}`)}async resetBackgroundTasks(){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null;let $=Date.now();if(this.backgroundTasks=this.backgroundTasks.map((Z)=>B$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$}),this.pendingBgTasks=[],this.backgroundSync)try{await this.backgroundSync}catch(Z){B(`session "${this.sessionName}": retrying terminal delegation update after: ${R(Z)}`)}if(await this.refreshBackgroundCardFull(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null,this.agentCards.releaseBackground(this.backgroundOwner),this.backgroundOwner=cQ(16).toString("hex"),this.backgroundTasks=[],this.nativeAgentTools.clear(),this.lastMainTaskToolUseId=null}startScheduledTurnCard($,Z,J,Q){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Y;try{Y=this.beginTurnOpen($,Z,!0)}catch(X){B(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${R(X)}`);return}let V=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${V.slice(0,78)}`,B(`session "${this.sessionName}": scheduled wakeup prompt=${Q??"MISS"}`),(async()=>{try{let X=await this.openTurnCard(Y,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(B(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),X&&this.currentTurn===X)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!X||this.currentTurn!==X){if(!this.ownsTurnOpen(Y))return;if(this.bgResumeCardless=!0,Y.sawResult)Y.sawResult=!1,B(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else B(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Y.sawResult)Y.sawResult=!1,B(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Y.terminalSuffix,{forcePush:Y.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Y)}})().catch((X)=>{B(`session "${this.sessionName}": scheduled turn-open handler failed: ${R(X)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Q=()=>this.proc===$&&this.procEpoch===J,Y=!1,V=!1,X=(H,z)=>{$.on(H,(W)=>{if(!Q()){if(!Y)Y=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(H)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(H!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(H)} while process stop is pending`);return}z(W)})};X("error",(H)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${H}`)}),X("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++,B(`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)B(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let H=this.pendingUserMessageCount>0,z=!H&&this.bgResumePending;if(!H&&!z)return;let W=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(L){B(`session "${this.sessionName}": init turn-open ownership conflict: ${R(L)}`);return}if(this.bgResumePending=!1,H)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=H?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let L of K){let j=this.currentBatchReactionIds.get(L);if(this.currentBatchReactionIds.delete(L),j)k0(L,j)}};(async()=>{try{let L=await this.openTurnCard(G,W,H?"user_message":"bg_task_resume");if(!Q()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),L&&this.currentTurn===L)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!L||this.currentTurn!==L){if(!this.ownsTurnOpen(G)){_();return}if(G.sawResult&&G.terminalSuffix)I(this.chatId,G.terminalSuffix);if(H)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,B(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else B(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,B(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(G.terminalSuffix,{forcePush:G.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(G)}})().catch((L)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${R(L)}`)})}),X("scheduled_turn_input",({text:H,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,H,z)}),X("conversation_materialized",({session_id:H,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==H){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${H} current=${$.sessionId??"MISS"} source=${z}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${H} source=${z}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:H,source:z,error:W})=>{if($.provider!=="codex"||$.sessionId!==H)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${R(W)}`,K=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,B(`session "${this.sessionName}": ${G} thread=${H} source=${z}`),K)I(this.chatId,`⚠️ ${G}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:H,diagnostics:z})=>{if(B(`session "${this.sessionName}": Codex account=${H}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)u(this.chatId,P$({phase:"warning",title:"部分账号 MISS",message:`${z.length} 个账号未参与选择`,details:z.join(`
258
+ `),hint:"详情:codex-accounts"})).catch((W)=>{B(`session "${this.sessionName}": 账号诊断卡失败: ${R(W)}`)})}),X("turn_started",({retry:H})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)B(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),H){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}),X("token_usage",({totalUsage:H})=>{if(this.persistResumableSessionId(),H)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(H)=>{this.handleTurnPlanUpdated(H)}),X("plan_delta",(H)=>{this.handlePlanDelta(H)}),X("context_compacted",(H)=>{this.handleContextCompacted(H)}),X("rate_limits_updated",(H)=>{if($.provider==="codex"&&!I0($.tokenSourceId)?.codexApiProvider)LX(H,v0($))}),X("thread_goal_updated",(H)=>{this.handleThreadGoalUpdated(H)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:H,parentToolUseId:z})=>{if(z)return;this.appendAssistant(H)}),X("assistant_block_stop",({parentToolUseId:H})=>{if(H)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:H,name:z,input:W,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(V6({active:this.backgroundTasks,pending:this.pendingBgTasks},G,H,z,W)),this.onBackgroundTaskChanged();return}if(!G&&(z==="Task"||z==="Agent"||$.provider==="dsh"&&(z==="subagent"||z==="subagent_fork"))){let K=this.currentTurn;if(K)this.startWorkingFooter(K),this.finalizeCurrentAssistantSegment(),K.openBatchI=null,K.taskCreateI=null,K.taskUpdateI=null;if(this.onMainThreadAdvance(),this.nativeAgentTools.set(H,{confirmed:!1,input:W}),$.provider==="claude")this.lastMainTaskToolUseId=H,this.applyBgStore(r4(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:W?.description||W?.name||"子 Agent",prompt:W?.prompt,subagent_type:W?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(RW(this,H,z,W),!G)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:H,content:z,is_error:W,parentToolUseId:G,input:K})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(H6({active:this.backgroundTasks,pending:this.pendingBgTasks},G,H,z,W)),this.onBackgroundTaskChanged();return}let _=!G&&this.nativeAgentTools.get(H);if(_){if(this.nativeAgentTools.delete(H),this.lastMainTaskToolUseId===H)this.lastMainTaskToolUseId=null;if(W||$.provider==="claude"&&!_.confirmed&&_.input?.run_in_background!==!0){let L=typeof z==="string"?z:Array.isArray(z)?z.map((q)=>typeof q?.text==="string"?q.text:JSON.stringify(q)).join(`
259
+ `):JSON.stringify(z)??"MISS",j=this.backgroundTasks.find((q)=>q.toolUseId===H);if(!j)this.applyBgStore(r4(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:_.input?.description||"子 Agent",prompt:_.input?.prompt})),j=this.backgroundTasks.find((q)=>q.toolUseId===H);this.applyBgStore(m3(this.bgStore(),{task_id:j.id,status:W?"failed":"completed",summary:L})),this.onBackgroundTaskChanged(!0)}Z2(this);return}TW(this,H,z,W,K)}),X("can_use_tool",(H)=>{SW(this,H)}),X("hook_callback",(H)=>{this.proc?.sendHookResponse(H.request_id,{})}),X("result",(H)=>{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",T=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${T} — ignored`),this.status="idle";return}let K=H?.is_error!==!0?this.recordTurnAnchor(H?.checkpoint):null;if(H?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,L=this.proc?.lastResult.is_error===!0,j=this.proc?.lastResult.subtype??"success",q=typeof H?.error==="string"&&H.error.trim()?H.error.trim():j,P,N=!1,D=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),U=[G,K].filter(Boolean).join(";")||null;if(U)P=`⚠️ ${U}`,N=!0;else if(_)P=L?`⚠️ ${D} ${q},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(L)P=`⚠️ ${D} ${q}`,N=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=P,this.openingTurnOwner.terminalForcePush=N;if(U&&!this.currentTurn&&!this.openingTurn)I(this.chatId,`⚠️ ${U}`);if(B(`session "${this.sessionName}": SDK result subtype=${j} isError=${L} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${N}`),this.closeTurnCard(P,{forcePush:N,hasFreshResult:!0}).catch((M)=>{B(`session "${this.sessionName}": result card close failed: ${R(M)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((M)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${R(M)}`)})}),X("bg_task_started",(H)=>{let z=H.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,W=z?this.nativeAgentTools.get(z):void 0;if(W)W.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${H.task_id} type=${H.task_type??"-"} subagent=${H.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(H.description??"").slice(0,40)}`),this.applyBgStore(r4(this.bgStore(),{...H,tool_use_id:z})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(H)=>{this.applyBgStore(J6(this.bgStore(),H)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(H)=>{this.applyBgStore(Q6(this.bgStore(),H)),this.onBackgroundTaskChanged(!!H.patch.status||H.patch.is_backgrounded===!0)}),X("bg_task_settled",(H)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${H.task_id} status=${H.status}`),this.applyBgStore(m3(this.bgStore(),H)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(H)=>{this.applyBgStore(X6(this.bgStore(),H.thread_id,H.item_id,H.tool,H.phase,H.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:H,signal:z,expected:W})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${H} signal=${z} expected=${W}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let j=$.conversationMaterializationFailure?.(),q=this.persistResumableSessionId(!1,$,!1),P=[j&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${R(j)}`:null,q].filter(Boolean).join(";");if(P)I(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${P}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}B(`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((j)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${R(j)}`)});let G=this.backendLabel($.provider),K=`code=${H??"null"}, signal=${z??"null"}`,_=W?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(_).catch((j)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${R(j)}`)});let L=this.waitForTurnCloses().catch((j)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${R(j)}`)});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 j=await Promise.allSettled([L,this.resetBackgroundTasks()]);for(let q of j)if(q.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${R(q.reason)}`);if(!W)await S(this.chatId,`⚠️ ${G} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((j)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${R(j)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?g7(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=m7(Z),Q=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Y=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Q,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Q,durationMs:Y}}currentContextTokens($=this.proc){if($?.provider==="claude"||$?.provider==="dsh")return $.lastContextTokens??null;let Z=$?.lastUsage;return X8(Z)}contextLimitForDisplay($=this.proc){return H8($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;if(this.modelSettingsBlockReason())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||this.modelSettingsBlockReason())return;let J;try{J=this.beginTurnOpen($,Z)}catch(Y){B(`session "${this.sessionName}": mid-turn open ownership conflict: ${R(Y)}`);return}let Q=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let z of Q)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 Y=Q.map((z)=>z.wireText).join(`
259
260
 
260
- `),X=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,H=await this.openTurnCard(J,X,"user_message");if(!H||this.currentTurn!==H){for(let z of Y){if(!z.msgId)continue;let G=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),G)k0(z.msgId,G)}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 G=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),G)k0(z.msgId,G)}this.status="stopped";return}try{if(!await this.sendClaimedUserText($,Q))return}catch(z){B(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${z}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await w(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($,T.footer,this.footerElement(Z)):!0;v0($);let Q=await R0($,b1({suffix:Z}));if(Y&&Q){await H$($);return}let V=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;B(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${V}`),await w(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,B(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${V.length}`);let X=this.runtimeModelSelection(),H=this.withModel(Y.initialFooter??"Waiting...(0s)",X),z=J8({sessionName:this.sessionName,turn:Q,provider:X.provider,model:X.model??void 0,effort:X.effort??"MISS",kind:J,userInputs:V,initialFooter:H,directStart:Y.directStart}),G=await u(this.chatId,z);if(!G){if(!this.ownsTurnOpen($))return null;if(B(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await w(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let W;try{W=await L$(G)}catch(j){if(B(`session "${this.sessionName}": id_convert failed: ${j}`),J==="user_message"&&this.ownsTurnOpen($))await w(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let K=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return X$(W,K),await this.terminalizeSupersededCard(W,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:W,...X,messageId:G,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(X$(W,K,(j,q)=>{this.onCardWriteFailure(_,W,j,q)}),this.currentTurn=_,Y.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let j=$.pendingCompactions.splice(0);B(`session "${this.sessionName}": replay ${j.length} context compaction event(s) buffered during card open`);for(let q of j)this.handleContextCompacted(q)}let L=this.takeOrphanAssistantText();if(L)this.appendAssistant(L),this.finalizeCurrentAssistantSegment();return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&S9($.cardId)<UA)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){B(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){B(`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(!x9(J,Y)){let X=Y?.operation??"unknown operation",H=Y?.elementId?` element=${Y.elementId}`:"";B(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${X}${H} code=${J??"n/a"} — not rotating`);let z=`${Z}:${X}:${Y?.elementId??""}:${J??"MISS"}`;if(!Q.cardWriteFailureNotices.has(z))Q.cardWriteFailureNotices.add(z),w(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${X}${H})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let V=Y?.capacityFingerprint;if(V){let X=Q.cardCapacityFailures.get(V);if(X!==void 0){if(B(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Y.operation} element=${Y.elementId??"MISS"} code=${J??"MISS"}`),!X)Q.cardCapacityFailures.set(V,!0),w(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(V,!1)}B(`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=(X,H)=>{if(!Q.value)Q.value={code:X,failure:H}};$.rotating=(async()=>{try{B(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${S9(Z)}`);let X=J8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),H=await u(this.chatId,X);if(!H){if(B(`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 L$(H)}catch(q){if(B(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${q}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await w(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}X$(z,2,(q,F)=>{if($.rotating){V(q,F);return}this.onCardWriteFailure($,z,q,F)});let G=$.assistantWriteInflight?.get(Z);if(G?.size)await Promise.allSettled([...G]);this.stopFooterStatus($),$.cardId=z,$.cardRotationFailed=!1,$.messageId=H,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let W=$.currentAssistantSegmentId,K=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,W&&K){let q=T.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=q,$.currentAssistantText=K,$.segmentTexts.set(q,K)}if(K)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)U0($.cardId,v1(this.taskBoard),{type:"insert_before",targetElementId:T.footer});if($.planLiveInserted)U0($.cardId,J9($.planSteps,$.planExplanation,T.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?T.taskBoardLive:T.footer});for(let q of $.contextCompactionPending.values()){if(q.cardId!==Z)continue;q.cardId=z,q.created=!1,q.createFailure=void 0;let F=T.contextCompact(q.i);q.createPromise=$4(z,Z9(q.i,q.notice,F),{type:"insert_before",targetElementId:T0($)}).then((R)=>{if(q.cardId===z)q.created=R.landed,q.createFailure=R.failure;return R.landed})}for(let[q,F]of _){if(W&&K&&q===W)continue;if(!e2(Z,q))continue;let R=$.assistantSegmentCount++,D=T.assistant(R);$.segmentTexts.set(D,F),await this.addCompletedAssistantSegment($,D,F)}iJ(this,Z,z,J,Y,$),await G1(Z),iJ(this,Z,z,J,Y,$);let L=new Set([T.taskBoardLive,T.planLive,...[...$.contextCompactionPending.values()].map((q)=>T.contextCompact(q.i))]);if(W)L.add(W);for(let q of J.values())if(q.output==null)L.add(T.tool(q.i));if(Wz(Z).some((q)=>!L.has(q)))$.cardCapacityFailures.clear();await G1(z);try{await dJ($,Z);let q=$.mathRenderInflight?.get(Z);if(q?.size)await Promise.allSettled([...q]);await G1(Z);let F=$.mathRendered?.get(Z);for(let[A,x]of _){if(W&&K&&A===W)continue;if(e2(Z,A))continue;if(F?.has(A))continue;await Y0(Z,A,this.completedAssistantElement(A,x))}let R=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",D=await A0(Z,T.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${R}`)),{notifyCardFailure:!1});v0(Z);let U=await R0(Z,b1({suffix:"\uD83D\uDCE8 转下一张"}));if(D&&U)await H$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${D} settings=${U}`),await w(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${D?"ok":"MISS"}, settings=${U?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(q){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${q}`)}B(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${z.slice(0,8)}…`)}finally{$.rotating=null;let X=Q.value;if(X&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,X.code,X.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=T.planUpdate($.planUpdateCount++);U0(Z,w6($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:T0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=T.goalUpdate(Z.goalUpdateCount++);U0(Z.cardId,v6($,J),{type:"insert_before",targetElementId:T0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=T.goalUpdate($.goalUpdateCount++);U0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
261
+ `),X=Q[Q.length-1]?.userOpenId??this.lastUserOpenId,H=await this.openTurnCard(J,X,"user_message");if(!H||this.currentTurn!==H){for(let z of Q){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 Q){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{if(!await this.sendClaimedUserText($,Y))return}catch(z){B(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${z}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await I(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 Q=J?await A0($,E.footer,this.footerElement(Z)):!0;g0($);let Y=await R0($,I1({suffix:Z}));if(Q&&Y){await G$($);return}let V=`footer=${Q?"ok":"MISS"}, settings=${Y?"ok":"MISS"}`;B(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${V}`),await I(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${V})。`)}async openTurnCard($,Z,J,Q={}){if(!this.ownsTurnOpen($))return null;this.bgResumePending=!1;let Y=++this.turnCounter,V=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=V[0]?.slice(0,80)??this.lastTurnUserPreview,B(`session "${this.sessionName}": openTurnCard turn=${Y} trigger=${J} inputs=${V.length}`);let X=this.runtimeModelSelection(),H=this.withModel(Q.initialFooter??"Waiting...(0s)",X),z=K8({sessionName:this.sessionName,turn:Y,provider:X.provider,model:X.model??void 0,effort:X.effort??"MISS",kind:J,userInputs:V,initialFooter:H,directStart:Q.directStart}),W=await u(this.chatId,z);if(!W){if(!this.ownsTurnOpen($))return null;if(B(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await I(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let G;try{G=await F$(W)}catch(j){if(B(`session "${this.sessionName}": id_convert failed: ${j}`),J==="user_message"&&this.ownsTurnOpen($))await I(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return null}let K=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return W$(G,K),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:G,...X,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(W$(G,K,(j,q)=>{this.onCardWriteFailure(_,G,j,q)}),this.currentTurn=_,Q.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let j=$.pendingCompactions.splice(0);B(`session "${this.sessionName}": replay ${j.length} context compaction event(s) buffered during card open`);for(let q of j)this.handleContextCompacted(q)}let L=this.takeOrphanAssistantText();if(L)this.appendAssistant(L),this.finalizeCurrentAssistantSegment();return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&f9($.cardId)<aA)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Q){let Y=this.currentTurn;if(Y!==$){B(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Y.cardId!==Z){B(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Y.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Y.rotating)return;if(Y.cardRotationFailed)return;if(!v9(J,Q)){let X=Q?.operation??"unknown operation",H=Q?.elementId?` element=${Q.elementId}`:"";B(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${X}${H} code=${J??"n/a"} — not rotating`);let z=`${Z}:${X}:${Q?.elementId??""}:${J??"MISS"}`;if(!Y.cardWriteFailureNotices.has(z))Y.cardWriteFailureNotices.add(z),I(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${X}${H})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let V=Q?.capacityFingerprint;if(V){let X=Y.cardCapacityFailures.get(V);if(X!==void 0){if(B(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Q.operation} element=${Q.elementId??"MISS"} code=${J??"MISS"}`),!X)Y.cardCapacityFailures.set(V,!0),I(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Q.operation}, element=${Q.elementId??"MISS"});其余输出继续处理。`);return}Y.cardCapacityFailures.set(V,!1)}B(`session "${this.sessionName}": confirmed card capacity limit (${J}) on card=${Y.cardId.slice(0,8)}… — rotating to fresh card`),Y.failureRotateCount++,this.startMidTurnRotate(Y)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Q}=$,Y={value:null},V=(X,H)=>{if(!Y.value)Y.value={code:X,failure:H}};$.rotating=(async()=>{try{B(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${f9(Z)}`);let X=K8({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),H=await u(this.chatId,X);if(!H){if(B(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await I(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let z;try{z=await F$(H)}catch(q){if(B(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${q}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await I(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}W$(z,2,(q,P)=>{if($.rotating){V(q,P);return}this.onCardWriteFailure($,z,q,P)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=z,$.cardRotationFailed=!1,$.messageId=H,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,K=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&K){let q=E.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=q,$.currentAssistantText=K,$.segmentTexts.set(q,K)}if(K)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)M0($.cardId,c1(this.taskBoard),{type:"insert_before",targetElementId:E.footer});if($.planLiveInserted)M0($.cardId,W9($.planSteps,$.planExplanation,E.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?E.taskBoardLive:E.footer});for(let q of $.contextCompactionPending.values()){if(q.cardId!==Z)continue;q.cardId=z,q.created=!1,q.createFailure=void 0;let P=E.contextCompact(q.i);q.createPromise=V4(z,z9(q.i,q.notice,P),{type:"insert_before",targetElementId:T0($)}).then((N)=>{if(q.cardId===z)q.created=N.landed,q.createFailure=N.failure;return N.landed})}for(let[q,P]of _){if(G&&K&&q===G)continue;if(!Y4(Z,q))continue;let N=$.assistantSegmentCount++,D=E.assistant(N);$.segmentTexts.set(D,P),await this.addCompletedAssistantSegment($,D,P)}QQ(this,Z,z,J,Q,$),await P1(Z),QQ(this,Z,z,J,Q,$);let L=new Set([E.taskBoardLive,E.planLive,...[...$.contextCompactionPending.values()].map((q)=>E.contextCompact(q.i))]);if(G)L.add(G);for(let q of J.values())if(q.output==null)L.add(E.tool(q.i));if(Oz(Z).some((q)=>!L.has(q)))$.cardCapacityFailures.clear();await P1(z);try{await JQ($,Z);let q=$.mathRenderInflight?.get(Z);if(q?.size)await Promise.allSettled([...q]);await P1(Z);let P=$.mathRendered?.get(Z);for(let[M,T]of _){if(G&&K&&M===G)continue;if(Y4(Z,M))continue;if(P?.has(M))continue;await Y0(Z,M,this.completedAssistantElement(M,T))}let N=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",D=await A0(Z,E.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${N}`)),{notifyCardFailure:!1});g0(Z);let U=await R0(Z,I1({suffix:"\uD83D\uDCE8 转下一张"}));if(D&&U)await G$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${D} settings=${U}`),await I(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${D?"ok":"MISS"}, settings=${U?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(q){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${q}`)}B(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${z.slice(0,8)}…`)}finally{$.rotating=null;let X=Y.value;if(X&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,X.code,X.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=E.planUpdate($.planUpdateCount++);M0(Z,u6($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:T0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=E.goalUpdate(Z.goalUpdateCount++);M0(Z.cardId,l6($,J),{type:"insert_before",targetElementId:T0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=E.goalUpdate($.goalUpdateCount++);M0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
261
262
 
262
- 已清除`},{type:"insert_before",targetElementId:T0($)})}handleContextCompacted($){let Z=WK($);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;B(`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<b7){B(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((D)=>D.startsWith("turn:")),V=Y??Q,X=V?this.contextCompactionReceipts.get(V):void 0;if(Y&&!X&&$.phase!=="start"&&Q){let D=this.contextCompactionReceipts.get(Q);if(!D?.hasItemAlias&&D?.completed&&Date.now()-D.completedAt<b7||!D?.hasItemAlias&&D?.completionKey&&J?.contextCompactionCompleting.has(D.completionKey))V=Q,X=D,D.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,D)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),B(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");B(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(V&&X?.completed){B(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${V}`);return}let H=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==H){this.rememberContextCompactionReceipt(Z,null,!0),B(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&X?.completionKey&&J.contextCompactionCompleting.has(X.completionKey)){B(`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__")){B(`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<b7){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let D=PA($);if(J.contextCompactionPending.has(D)||J.contextCompactionCompleted.has(D)){B(`session "${this.sessionName}": duplicate context compaction start ignored key=${D}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,H,!1);let U=J.contextCompactCount++,A=J.cardId,x=T.contextCompact(U),S={i:U,cardId:A,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};S.createPromise=$4(A,Z9(U,$,x),{type:"insert_before",targetElementId:T0(J)}).then((h)=>{if(S.cardId===A)S.created=h.landed,S.createFailure=h.failure;return h.landed}),J.contextCompactionPending.set(D,S),B(`session "${this.sessionName}": context compaction start #${U+1} key=${D}`),Z4(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){B(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<b7){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:qA(J),W=G?J.contextCompactionPending.get(G):void 0,K=G??z??"__anonymous__";if(J.contextCompactionCompleting.has(K)){B(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=FA(W?.notice,$),L=J.contextCompactionEndOnly.get(K),j=W?.i??L??J.contextCompactCount++;if(!W&&L===void 0)J.contextCompactionEndOnly.set(K,j);J.contextCompactionCompleting.add(K);let q=[...new Set([...WK(W?.notice??{}),...Z])];if(q.length>0)this.rememberContextCompactionReceipt(q,H,!1,K);let F=T.contextCompact(j),R=Z9(j,_,F);B(`session "${this.sessionName}": context compaction completion write #${j+1} key=${K}`),(async()=>{let D=!1;if(!W)while(!0){let U=J.cardId;if(D=await u1(U,R,{type:"insert_before",targetElementId:T0(J)}),D)break;let A=J.rotating;if(A){await A;continue}if(J.cardId!==U)continue;break}else while(!0){let U=W.cardId;if(await W.createPromise,W.cardId!==U)continue;if(W.created)D=await A0(U,F,R);else{if(Gz(W.createFailure?.code,W.createFailure))Kz(U,F),D=await A0(U,F,R,{notifyCardFailure:!1});if(!D)D=await u1(U,R,{type:"insert_before",targetElementId:T0(J)})}if(W.cardId!==U)continue;if(D){W.created=!0;break}let A=J.rotating;if(A){await A;continue}if(W.cardId!==U)continue;break}if(J.contextCompactionCompleting.delete(K),!D){B(`session "${this.sessionName}": context compaction completion write MISS #${j+1} key=${K}`);return}if(G&&J.contextCompactionPending.get(G)===W)J.contextCompactionPending.delete(G);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",q.length>0){let U=[...this.contextCompactionReceipts.entries()].filter(([,A])=>A.completionKey===K).map(([A])=>A);this.rememberContextCompactionReceipt([...new Set([...q,...U])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${j+1} key=${K}`)})().catch((D)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${N(D)}`)}),Z4(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>AA){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,H]of this.contextCompactionReceipts)if(H===V)this.contextCompactionReceipts.delete(X)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){B(`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))B(`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?T.taskBoardLive:T.footer;Z.planLiveInserted=!0,U0(Z.cardId,J9(Z.planSteps,Z.planExplanation,T.planLive),{type:"insert_before",targetElementId:J})}else Y0(Z.cardId,T.planLive,J9(Z.planSteps,Z.planExplanation,T.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){B(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)B(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){B(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")B(`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&&Z8(Z)===Z8(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++,X=T.assistant(V);Z.currentAssistantSegmentId=X,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);Z4(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
263
+ 已清除`},{type:"insert_before",targetElementId:T0($)})}handleContextCompacted($){let Z=CK($);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;B(`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<c5){B(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((D)=>D.startsWith("turn:")),V=Q??Y,X=V?this.contextCompactionReceipts.get(V):void 0;if(Q&&!X&&$.phase!=="start"&&Y){let D=this.contextCompactionReceipts.get(Y);if(!D?.hasItemAlias&&D?.completed&&Date.now()-D.completedAt<c5||!D?.hasItemAlias&&D?.completionKey&&J?.contextCompactionCompleting.has(D.completionKey))V=Y,X=D,D.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,D)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),B(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");B(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(V&&X?.completed){B(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${V}`);return}let H=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==H){this.rememberContextCompactionReceipt(Z,null,!0),B(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&X?.completionKey&&J.contextCompactionCompleting.has(X.completionKey)){B(`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__")){B(`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<c5){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let D=uA($);if(J.contextCompactionPending.has(D)||J.contextCompactionCompleted.has(D)){B(`session "${this.sessionName}": duplicate context compaction start ignored key=${D}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,H,!1);let U=J.contextCompactCount++,M=J.cardId,T=E.contextCompact(U),x={i:U,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};x.createPromise=V4(M,z9(U,$,T),{type:"insert_before",targetElementId:T0(J)}).then((w)=>{if(x.cardId===M)x.created=w.landed,x.createFailure=w.failure;return w.landed}),J.contextCompactionPending.set(D,x),B(`session "${this.sessionName}": context compaction start #${U+1} key=${D}`),X4(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){B(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<c5){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let W=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:lA(J),G=W?J.contextCompactionPending.get(W):void 0,K=W??z??"__anonymous__";if(J.contextCompactionCompleting.has(K)){B(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=dA(G?.notice,$),L=J.contextCompactionEndOnly.get(K),j=G?.i??L??J.contextCompactCount++;if(!G&&L===void 0)J.contextCompactionEndOnly.set(K,j);J.contextCompactionCompleting.add(K);let q=[...new Set([...CK(G?.notice??{}),...Z])];if(q.length>0)this.rememberContextCompactionReceipt(q,H,!1,K);let P=E.contextCompact(j),N=z9(j,_,P);B(`session "${this.sessionName}": context compaction completion write #${j+1} key=${K}`),(async()=>{let D=!1;if(!G)while(!0){let U=J.cardId;if(D=await s1(U,N,{type:"insert_before",targetElementId:T0(J)}),D)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==U)continue;break}else while(!0){let U=G.cardId;if(await G.createPromise,G.cardId!==U)continue;if(G.created)D=await A0(U,P,N);else{if(Az(G.createFailure?.code,G.createFailure))Nz(U,P),D=await A0(U,P,N,{notifyCardFailure:!1});if(!D)D=await s1(U,N,{type:"insert_before",targetElementId:T0(J)})}if(G.cardId!==U)continue;if(D){G.created=!0;break}let M=J.rotating;if(M){await M;continue}if(G.cardId!==U)continue;break}if(J.contextCompactionCompleting.delete(K),!D){B(`session "${this.sessionName}": context compaction completion write MISS #${j+1} key=${K}`);return}if(W&&J.contextCompactionPending.get(W)===G)J.contextCompactionPending.delete(W);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",q.length>0){let U=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===K).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...q,...U])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${j+1} key=${K}`)})().catch((D)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${R(D)}`)}),X4(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,Q){let Y={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Q?{}:{completionKey:Q},hasItemAlias:$.some((V)=>V.startsWith("item:"))};for(let V of $)this.contextCompactionReceipts.delete(V),this.contextCompactionReceipts.set(V,Y);while(this.contextCompactionReceipts.size>oA){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,H]of this.contextCompactionReceipts)if(H===V)this.contextCompactionReceipts.delete(X)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){B(`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))B(`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?E.taskBoardLive:E.footer;Z.planLiveInserted=!0,M0(Z.cardId,W9(Z.planSteps,Z.planExplanation,E.planLive),{type:"insert_before",targetElementId:J})}else Y0(Z.cardId,E.planLive,W9(Z.planSteps,Z.planExplanation,E.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){B(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)B(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){B(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")B(`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&&G8(Z)===G8(J))return;let Q=this.currentTurn;if(Q){if(this.startWorkingFooter(Q),Q.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Q.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++,X=E.assistant(V);Z.currentAssistantSegmentId=X,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Y=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);X4(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
263
264
 
264
- `).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;B(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),E(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
265
+ `).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;B(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),S(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
265
266
 
266
- ${J}`)}completedAssistantElement($,Z){if(fJ(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 tz(Y);if(!await A0(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){B(`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),B(`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 u1(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return B(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(fJ(J)){let H=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((z)=>B(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(H),H.finally(()=>$.mathRenderInflight?.get(Y)?.delete(H))}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 原始回复:
267
+ ${J}`)}completedAssistantElement($,Z){if(nJ(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Q)=>Q.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Q.text).trim()||" "}:{...Q.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,Q){let Y=await KW(Q);if(!await A0(Z,J,this.mathAssistantContainer(J,Y.blocks),{notifyCardFailure:!1})){B(`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),B(`session "${this.sessionName}": math rendered ${J} (${Y.renderedImageCount} img, ${Y.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Q=$.cardId,Y=T0($),V=(async()=>{if(!await s1(Q,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Y}))return B(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Q}`),!1;if(nJ(J)){let H=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((z)=>B(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(H),H.finally(()=>$.mathRenderInflight?.get(Q)?.delete(H))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Q)??$.assistantWriteInflight.set(Q,new Set),$.assistantWriteInflight.get(Q).add(V),V.finally(()=>$.assistantWriteInflight?.get(Q)?.delete(V)),V}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Q=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
267
268
 
268
- ${J}`;if(!await E(this.chatId,Y))B(`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 yz($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return $0($)}sendOutboundPath($,Z){let J=V7($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!LA(J)){B(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}B(`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),T9(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){B(`session "${this.sessionName}": file delivery rejected: ${N(Q)}`),E(this.chatId,`❌ 文件交付失败:${N(Q)}`)}}createFileDeliveryForTurn($){return yW({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}=T2(Date.now()-$.footerStatusStartedAt,k7()),X=Z===KK?this.proc?.lastThinkingTokens:null,H=typeof X==="number"?` · 约 ${X} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${H} (${V})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:V}=T2(Date.now()-$.footerStatusStartedAt,k7());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(V)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,KK)}startWritingFooter($){this.startFooterStatus($,DA)}startWorkingFooter($){this.startFooterStatus($,MA)}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 X=await Y.readUsage();if(X.state==="ok"&&X.kind!=="balance"){let H=X.windows.find((G)=>G.kind==="fiveHour");if(Y.kind==="claude-subscription"){let G=bz(X,V),W={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(H??W,G??W)}let z=X.windows.find((G)=>G.kind==="weekly");if(H||z)return this.fmtDualWindowSuffix(H??null,z??null)}return` | ${$Z(X)}`}if($==="codex"){let X=Q??(Z?.provider==="codex"?U6(y0(Z)):null);if(!X)return" | 额度 MISS";let H=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits&&y0(Z)===X.accountId?Z:null,z=H?await i3(()=>{if(y0(H)!==X.accountId)throw Error("Codex 额度查询所属账号已切换");return H.readRateLimits()},X.accountId):null,G=z?.state==="ok"?z:X.read();if(!G)return" | 额度 MISS";return this.fmtDualWindowSuffix(G.fiveHour,G.weekly)}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(V)=>{if(!V)return null;if(V.percent==null)return"MISS";let X=V.resetsAt&&V.resetsAt.getTime()>Date.now()?Z1(V.resetsAt):"",H=`${Math.round(V.percent)}%`;return X?`${X}·${H}`:H},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)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"?V0(Y.tokenSourceId??this.selectedTokenSourceId,y0(Y)):this.currentTokenSource(),codexUsage:Y?.provider==="codex"?U6(y0(Y)):null,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 dJ(Y),Y.fileDelivery)try{for(let U of await Y.fileDelivery.finish())Y.outboundSentPaths.add(U)}catch(U){B(`session "${this.sessionName}": file delivery close failed: ${N(U)}`),await w(this.chatId,`❌ 文件交付收尾失败:${N(U)}`)}finally{this.fileDeliveries.delete(Y.fileDelivery)}this.stopFooterStatus(Y);let Q=(Date.now()-Y.startedAt)/1000,V=Y.cardId,X=Y.segmentTexts;await G1(V);let H=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:U,currentAssistantText:A}=Y;if(!await this.addCompletedAssistantSegment(Y,U,A))H.set(U,A);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let z=Y.assistantWriteInflight?.get(V);if(z?.size)await Promise.allSettled([...z]);let G=Y.mathRenderInflight?.get(V);if(G?.size)await Promise.allSettled([...G]);let W=Y.mathRendered?.get(V);for(let[U,A]of X){if(e2(V,U)){H.set(U,A);continue}if(W?.has(U))continue;await Y0(V,U,this.completedAssistantElement(U,A))}if(Y.cardRotationFailed)for(let[U,A]of X)H.set(U,A);let K=Z?Z:"✅",_=[`${K} ⏱ ${D0(Q)}`];if(J.hasFreshResult){let{contextTokens:U,contextLimit:A}=$,x=Y.provider==="claude",S=k6(U,A,x?0:void 0);if(S)_.push(`\uD83E\uDDE0 ${S}`);let h=$.lastTurnDelta?.costUsd??0;if(h>0)_.push(`\uD83D\uDCB0 $${h.toFixed(3)}`)}if(Y.contextCompactCount>0)_.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)_.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let L=this.modelLine(Y);if(L)_.push(L);let j=_.join(" | "),q=J.hasFreshResult?y6($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Y.model)):"",F=q?`${j}
269
- ${q}`:j,R=await A0(V,T.footer,this.footerElement(F));v0(V);let D=await R0(V,b1({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(R&&D)await H$(V);else{let U=`footer=${R?"ok":"MISS"}, settings=${D?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${U}`),await w(this.chatId,`⚠️ 对话卡片终态写入失败 (${U})。本轮已结束: ${K}`)}for(let U of H.values())await this.sendAssistantTextFallback(U,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)m1(Y.messageId,[Y.userOpenId])}}});function z$($){return{card:{type:"raw",data:$}}}import{randomUUID as OA}from"node:crypto";function kY($){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(y0($.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:$$().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 jK($,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 X={};for(let[H,z]of Object.entries(V.value)){if(!RA.has(H))throw Error(`unsupported model action field: ${H}`);if(H==="page"){if(typeof z!=="number"||!Number.isSafeInteger(z)||z<0)throw Error("invalid page");X.page=z}else{if(typeof z!=="string"||!z.trim()||z.length>1024)throw Error(`invalid ${H}`);X[H]=z.trim()}}if(!NA.has(String(X.kind)))throw Error("only model panel actions are supported");for(let H of["panel_id","source_id"])if(!X[H])throw Error(`${H} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(X.kind))&&!X.model)throw Error("model required");if(X.kind==="model_effort_select"&&!X.effort)throw Error("effort required");if(X.kind==="model_page"&&X.page===void 0)throw Error("page required");if(X.kind==="model_list_open"&&X.mode!=="select"&&X.mode!=="add")throw Error("invalid model list mode");if(X.provider!==void 0&&!M$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${OA()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:V.message_id},action:{tag:"button",value:X}}}var NA,RA;var LK=O(()=>{j0();Z0();w0();NA=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"]),RA=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as TA}from"node:http";import{randomUUID as EA}from"node:crypto";function DK($){if($.allowReply&&$.buttons?.length)throw Error(FK);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")}`,X=[];for(let z of $.images??[])if(z.key)X.push({tag:"img",img_key:z.key,alt:{tag:"plain_text",content:"screenshot"}});else X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${z.src}</font>`});if(X.push({tag:"markdown",content:u5($.text??"")||"_(空消息)_"}),$.resolution){let z=$.resolution,G=z.kind==="text"?"已回复":`已选择:${z.text}`,W;if(z.status==="processing")W=`<font color='blue'>⏳ ${G} · 推送中…</font>`;else if(z.status==="failed")W=`<font color='red'>⚠️ ${z.kind==="text"?G:`已选:${z.text}`} · 回调失败:${$0(z.detail??"未知")} · ${V}</font>`;else if(z.status==="delivered")W=`<font color='green'>✅ ${G} · 反馈已送达 · ${V}</font>`;else if(z.status==="unknown")W=`<font color='red'>⚠️ ${G} · ${z.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${V}</font>`;else W=`<font color='green'>✅ ${G} · ${V}</font>`;if(X.push({tag:"markdown",content:W}),z.status==="delivered"&&z.reply)X.push({tag:"markdown",content:$0(z.reply)})}let H=Y&&(!$.resolution||$.resolution.status==="failed");if(H&&$.buttons?.length)X.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(X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${V}</font>`}),H&&$.allowReply)X.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:X}}}function B1($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${$0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:$0(Z.response.text)});if(Y==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
270
- 你的下一条文字优先用于这条通知,完成后再回答 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 X=J?.detail??Z.error;if(X)V.push({tag:"markdown",content:`<font color='red'>${$0(X)}</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:$0(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 bA($){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(!CA.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>PK)return{error:`button "${Q}" text > ${PK} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let X=String(Y.type??"default").toLowerCase(),H=SA.has(X)?X:"default";J.push({id:Q,text:V,type:H})}return{buttons:J}}function kA($){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 MK($){try{let Z=TA((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((X)=>X?void 0:qK(J,Y)):qK(J,Y)).catch((X)=>{if(B(`notify: handler crash: ${X?.message??X}`),!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)=>{B(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{B(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){B(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function qK($,Z,J=J0){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(l,M)=>{Z.statusCode=l,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(M)},V=(l,M)=>{Z.statusCode=l,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(M))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
269
+ ${J}`;if(!await S(this.chatId,Q))B(`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 nz($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return Z0($)}sendOutboundPath($,Z){let J=q5($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!cA(J)){B(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}B(`session "${this.sessionName}": outbound send from ${Z}: ${J}`);try{let Y=Q?.fileDeliveryMode??(this.proc?this.procFileDeliveryModes.get(this.proc):void 0)??this.getFileDeliveryMode();if(Q)Q.fileDeliveryMode=Y;if(Y==="chat"){Q?.outboundSentPaths.add(J),w9(this.chatId,J);return}if(!Q)throw Error("当前没有可关联的交付轮次");if(!Q.fileDelivery)Q.fileDelivery=this.createFileDeliveryForTurn(Q),this.fileDeliveries.add(Q.fileDelivery);Q.fileDelivery.add(J)}catch(Y){B(`session "${this.sessionName}": file delivery rejected: ${R(Y)}`),S(this.chatId,`❌ 文件交付失败:${R(Y)}`)}}createFileDeliveryForTurn($){return eG({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 Q=()=>{if($.footerStatusLabel!==Z)return;let{label:V}=w2(Date.now()-$.footerStatusStartedAt,u5()),X=Z===bK?this.proc?.lastThinkingTokens:null,H=typeof X==="number"?` · 约 ${X} tokens`:"";this.replaceFooterContent($.cardId,this.withModel(`${Z}${H} (${V})`))},Y=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:V}=w2(Date.now()-$.footerStatusStartedAt,u5());$.footerStatusHandle=setTimeout(()=>{Q(),Y()},Math.max(1,Math.ceil(V)))};Q(),Y()}startThinkingFooter($){this.startFooterStatus($,bK)}startWritingFooter($){this.startFooterStatus($,iA)}startWorkingFooter($){this.startFooterStatus($,nA)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Q,Y,V){if(J&&(!Q||!Q.enabled||Q.agent!==$))return" | 额度 MISS";if(Q?.agent===$&&Q.enabled&&($==="claude"||$==="dsh"||Q.codexApiProvider)){let X=await Q.readUsage();if(X.state==="ok"&&X.kind!=="balance"){let H=X.windows.find((W)=>W.kind==="fiveHour");if(Q.kind==="claude-subscription"){let W=dz(X,V),G={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(H??G,W??G)}let z=X.windows.find((W)=>W.kind==="weekly");if(H||z)return this.fmtDualWindowSuffix(H??null,z??null)}return` | ${WZ(X)}`}if($==="codex"){let X=Y??(Z?.provider==="codex"?C6(v0(Z)):null);if(!X)return" | 额度 MISS";let H=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits&&v0(Z)===X.accountId?Z:null,z=H?await Z8(()=>{if(v0(H)!==X.accountId)throw Error("Codex 额度查询所属账号已切换");return H.readRateLimits()},X.accountId):null,W=z?.state==="ok"?z:X.read();if(!W)return" | 额度 MISS";return this.fmtDualWindowSuffix(W.fiveHour,W.weekly)}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(V)=>{if(!V)return null;if(V.percent==null)return"MISS";let X=V.resetsAt&&V.resetsAt.getTime()>Date.now()?G1(V.resetsAt):"",H=`${Math.round(V.percent)}%`;return X?`${X}·${H}`:H},Q=J($),Y=J(Z);if(Q&&Y)return` | ${Q}·[${Y}]`;if(Q)return` | ${Q}`;if(Y)return` | [${Y}]`;return" | 额度 MISS"}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Q)=>Q.status==="rejected").map((Q)=>Q.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 Q=this.proc,Y={turn:J,proc:Q,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Q),contextLimit:this.contextLimitForDisplay(Q),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:Q?.provider==="codex"?H0(Q.tokenSourceId??this.selectedTokenSourceId,v0(Q)):this.currentTokenSource(),codexUsage:Q?.provider==="codex"&&!I0(Q.tokenSourceId)?.codexApiProvider?C6(v0(Q)):null,currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let V=this.finishTurnCardClose(Y,$,Z).finally(()=>this.releaseTurnCloseReactions(Y));return this.turnCloseInflight.add(V),V.then(()=>{this.turnCloseInflight.delete(V)},()=>{this.turnCloseInflight.delete(V)}),V}async finishTurnCardClose($,Z,J={}){let{turn:Q}=$;if(Q.rotating)await Q.rotating;if(await JQ(Q),Q.fileDelivery)try{for(let U of await Q.fileDelivery.finish())Q.outboundSentPaths.add(U)}catch(U){B(`session "${this.sessionName}": file delivery close failed: ${R(U)}`),await I(this.chatId,`❌ 文件交付收尾失败:${R(U)}`)}finally{this.fileDeliveries.delete(Q.fileDelivery)}this.stopFooterStatus(Q);let Y=(Date.now()-Q.startedAt)/1000,V=Q.cardId,X=Q.segmentTexts;await P1(V);let H=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:U,currentAssistantText:M}=Q;if(!await this.addCompletedAssistantSegment(Q,U,M))H.set(U,M);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let z=Q.assistantWriteInflight?.get(V);if(z?.size)await Promise.allSettled([...z]);let W=Q.mathRenderInflight?.get(V);if(W?.size)await Promise.allSettled([...W]);let G=Q.mathRendered?.get(V);for(let[U,M]of X){if(Y4(V,U)){H.set(U,M);continue}if(G?.has(U))continue;await Y0(V,U,this.completedAssistantElement(U,M))}if(Q.cardRotationFailed)for(let[U,M]of X)H.set(U,M);let K=Z?Z:"✅",_=[`${K} ⏱ ${U0(Y)}`];if(J.hasFreshResult){let{contextTokens:U,contextLimit:M}=$,T=Q.provider==="claude",x=p6(U,M,T?0:void 0);if(x)_.push(`\uD83E\uDDE0 ${x}`);let w=$.lastTurnDelta?.costUsd??0;if(w>0)_.push(`\uD83D\uDCB0 $${w.toFixed(3)}`)}if(Q.contextCompactCount>0)_.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)_.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let L=this.modelLine(Q);if(L)_.push(L);let j=_.join(" | "),q=J.hasFreshResult?c6($.lastTurnUsage)+(Q.cardRotationFailed?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Q.model)):"",P=q?`${j}
270
+ ${q}`:j,N=await A0(V,E.footer,this.footerElement(P));g0(V);let D=await R0(V,I1({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(N&&D)await G$(V);else{let U=`footer=${N?"ok":"MISS"}, settings=${D?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${U}`),await I(this.chatId,`⚠️ 对话卡片终态写入失败 (${U})。本轮已结束: ${K}`)}for(let U of H.values())await this.sendAssistantTextFallback(U,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.cardRotationFailed)n1(Q.messageId,[Q.userOpenId])}}});function K$($){return{card:{type:"raw",data:$}}}import{randomUUID as sA}from"node:crypto";function dQ($){return{session_name:$.sessionName,chat_id:$.chatId,status:$.status,running:$.isRunning(),native_session_id:$.proc?.sessionId??null,codex_account:$.proc?.provider==="codex"&&$.proc.isAlive()?{name:y.get(v0($.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((Q)=>({model:Q.model,provider:Q.provider,source_id:Q.sourceId,efforts:Q.efforts.map((Y)=>Y.effort),origin:Q.origin}))})),sources:J$().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 yK($,Z,J,Q,Y){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(!Y||V.message_id!==Y)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!==Q)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 X={};for(let[H,z]of Object.entries(V.value)){if(!rA.has(H))throw Error(`unsupported model action field: ${H}`);if(H==="page"){if(typeof z!=="number"||!Number.isSafeInteger(z)||z<0)throw Error("invalid page");X.page=z}else{if(typeof z!=="string"||!z.trim()||z.length>1024)throw Error(`invalid ${H}`);X[H]=z.trim()}}if(!tA.has(String(X.kind)))throw Error("only model panel actions are supported");for(let H of["panel_id","source_id"])if(!X[H])throw Error(`${H} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(X.kind))&&!X.model)throw Error("model required");if(X.kind==="model_effort_select"&&!X.effort)throw Error("effort required");if(X.kind==="model_page"&&X.page===void 0)throw Error("page required");if(X.kind==="model_list_open"&&X.mode!=="select"&&X.mode!=="add")throw Error("invalid model list mode");if(X.provider!==void 0&&!O$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${sA()}`,operator:{open_id:Z.sender_open_id},context:{open_chat_id:Z.chat_id,open_message_id:V.message_id},action:{tag:"button",value:X}}}var tA,rA;var vK=O(()=>{G0();e();f0();tA=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"]),rA=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as eA}from"node:http";import{randomUUID as $O}from"node:crypto";function gK($){if($.allowReply&&$.buttons?.length)throw Error(IK);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Q=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Y=new Date,V=`${String(Y.getHours()).padStart(2,"0")}:${String(Y.getMinutes()).padStart(2,"0")}`,X=[];for(let z of $.images??[])if(z.key)X.push({tag:"img",img_key:z.key,alt:{tag:"plain_text",content:"screenshot"}});else X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${z.src}</font>`});if(X.push({tag:"markdown",content:r7($.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(X.push({tag:"markdown",content:G}),z.status==="delivered"&&z.reply)X.push({tag:"markdown",content:Z0(z.reply)})}let H=Q&&(!$.resolution||$.resolution.status==="failed");if(H&&$.buttons?.length)X.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(X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${V}</font>`}),H&&$.allowReply)X.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:Q?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:X}}}function A1($,Z,J){let Q=J?.status??Z.status,Y={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(Q==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
271
+ 你的下一条文字优先用于这条通知,完成后再回答 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(Q==="cancelled"&&Z.cancelReason==="switched")V.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let X=J?.detail??Z.error;if(X)V.push({tag:"markdown",content:`<font color='red'>${Z0(X)}</font>`});if(Q==="failed")V.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Q==="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:Y[Q]},template:Q==="failed"||Q==="unknown"?"red":Q==="delivered"||Q==="done"?"green":"blue"},body:{elements:V}}}function YO($){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 Q of $){if(!Q||typeof Q!=="object")return{error:"each button must be an object"};let Y=String(Q.id??"").trim(),V=String(Q.text??"").trim();if(!QO.test(Y))return{error:`button id "${Y.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!V)return{error:`button "${Y}" missing text`};if(V.length>fK)return{error:`button "${Y}" text > ${fK} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let X=String(Q.type??"default").toLowerCase(),H=JO.has(X)?X:"default";J.push({id:Y,text:V,type:H})}return{buttons:J}}function VO($){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 Q=J.hostname.replace(/^\[|]$/g,"");if(Q!=="127.0.0.1"&&Q!=="localhost"&&Q!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function mK($){try{let Z=eA((J,Q)=>{let Y=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Q,Y).then((X)=>X?void 0:hK(J,Q)):hK(J,Q)).catch((X)=>{if(B(`notify: handler crash: ${X?.message??X}`),!Q.headersSent)Q.statusCode=500,Q.setHeader("content-type","text/plain; charset=utf-8"),Q.end("internal error");else try{Q.end()}catch{}})});Z.on("error",(J)=>{B(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{B(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){B(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function hK($,Z,J=J0){let Q=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Y=(l,A)=>{Z.statusCode=l,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(A)},V=(l,A)=>{Z.statusCode=l,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(A))};if($.method==="GET"&&Q.pathname==="/")return Y(200,`lodestar notify
271
272
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
272
273
  `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
273
274
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
274
275
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
275
276
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
276
277
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
277
- `);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 M=h$(l);if(!M)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,VG(M))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let X="";for await(let l of $)X+=l.toString();let H={};try{H=JSON.parse(X)}catch{return Q(400,"bad json")}if(!H||typeof H!=="object"||Array.isArray(H))return Q(400,"body must be an object");if(H.allow_reply!==void 0&&typeof H.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let z=H.allow_reply===!0,G=String(H.project??"").trim(),W=String(H.text??""),K=String(H.title??"").trim(),_=String(H.level??"info").toLowerCase();if(!G)return Q(400,'missing "project"');if(!W)return Q(400,'missing "text"');let{buttons:L,error:j}=bA(H.buttons);if(j)return Q(400,j);let{url:q,error:F}=kA(H.callback);if(F)return Q(400,F);let R=!!(L&&L.length);if(R&&z)return Q(400,FK);let D=R||z,U=q??"",A=xA.has(_)?_:"info",x=K||G,S=J.sanitizeSessionName(G),h=J.chatIdForSession(S);if(!h)return B(`notify: project "${G}" (sanitized "${S}") has no chat binding → 404`),Q(404,`project "${G}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let y=Array.isArray(H.images)?H.images:[],g=[];for(let l of y){let M=String(l??"").trim();if(!M)continue;let b=await J.uploadImageKey(M);g.push({key:b??"",src:M})}let C=D?`nf_${EA()}`:"",I=DK({title:x,text:W,level:A,images:g,buttons:L,allowReply:z,notifyId:C}),c=await J.sendCard(h,I);if(!c)return B(`notify: sendCard failed → 502 (project="${G}" chat=${h.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(D&&C){let l={notifyId:C,callbackUrl:U,chatId:h,messageId:c,project:G,title:x,text:W,level:A,imageKeys:g,buttons:L,allowReply:z,createdAt:Date.now()};YG(l)}B(`notify: → ${G} (${h.slice(0,8)}…) level=${A} bytes=${W.length} images=${g.length} buttons=${L?.length??0} allowReply=${z} push=${D&&!!U?1:0} msg=${c}`),V(200,{ok:!0,chat_id:h,message_id:c,...C?{notify_id:C}:{}})}function J2($,Z){return DK({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var xA,SA,CA,PK=64,FK='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var y7=O(()=>{f();r();C0();c9();xA=new Set(["info","warn","error"]),SA=new Set(["default","primary","danger"]),CA=/^[A-Za-z0-9_-]{1,64}$/});var OK=aY((bw,AK)=>{var{readFileSync:yA,rmSync:wA}=X2("node:fs"),{homedir:UK}=X2("node:os"),{join:s9}=X2("node:path"),{managedClaudePluginDir:vA}=i7();function fA($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Y=Z??[s9(UK(),".codex","skills"),s9(UK(),".claude","skills"),s9(vA(),"skills")],Q=[];for(let V of Y){let X=s9(V,$),H=s9(X,"SKILL.md"),z;try{z=yA(H,"utf8")}catch(K){if(K.code==="ENOENT")continue;let _=Error(`skill: obsolete removal failed (${H}): ${K}`,{cause:K});J(_.message),Q.push(_);continue}let G=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(z)?.[1],W=/^name:[ \t]*(?:"([^"]*)"|'([^']*)'|([^\s#]+))[ \t]*$/m.exec(G??"");if(!W||(W[1]??W[2]??W[3])!==$){J(`skill: obsolete path preserved because ownership is unclear ${H}`);continue}try{wA(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let _=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(_.message),Q.push(_)}}if(Q.length)throw AggregateError(Q,`Failed to remove obsolete Skill ${$}`)}AK.exports={removeManagedSkill:fA}});import{existsSync as RK,readFileSync as TK}from"node:fs";import{homedir as NK}from"node:os";import{join as t9}from"node:path";function w7($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[t9(NK(),".codex","skills"),t9(NK(),".claude","skills")];for(let Y of J){let Q=t9(Y,$.name,"SKILL.md");try{let V=RK(Q)?TK(Q,"utf8"):null;if(V===$.body)continue;g0(Q,$.body),B(`skill: ${V===null?"installed":"updated"} ${Q}`)}catch(V){B(`skill: sync failed (${Q}): ${V}`)}}if(!Z)hA($,z2)}function hA($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=t9(Z,".claude-plugin","plugin.json"),Y=t9(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)+`
278
- `;for(let[V,X]of[[J,Q],[Y,$.body]])try{let H=RK(V)?TK(V,"utf8"):null;if(H===X)continue;g0(V,X),B(`skill: ${H===null?"installed":"updated"} ${V}`)}catch(H){B(`skill: Claude plugin sync failed (${V}): ${H}`)}}function v7($,Z){EK.removeManagedSkill($,Z,B)}var EK;var f7=O(()=>{f();x0();Q0();EK=nY(OK(),1)});function IA($){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`---
279
- name: ${xK}
278
+ `);if($.method==="GET"&&Q.pathname.startsWith("/notify/result/")){let l=decodeURIComponent(Q.pathname.slice(15)).trim();if(!l)return Y(400,"missing notify_id in path");let A=d$(l);if(!A)return V(404,{error:"unknown notify_id",notify_id:l});return V(200,DW(A))}if($.method!=="POST"||Q.pathname!=="/notify")return Y(405,"use POST /notify");let X="";for await(let l of $)X+=l.toString();let H={};try{H=JSON.parse(X)}catch{return Y(400,"bad json")}if(!H||typeof H!=="object"||Array.isArray(H))return Y(400,"body must be an object");if(H.allow_reply!==void 0&&typeof H.allow_reply!=="boolean")return Y(400,'"allow_reply" must be a boolean');let z=H.allow_reply===!0,W=String(H.project??"").trim(),G=String(H.text??""),K=String(H.title??"").trim(),_=String(H.level??"info").toLowerCase();if(!W)return Y(400,'missing "project"');if(!G)return Y(400,'missing "text"');let{buttons:L,error:j}=YO(H.buttons);if(j)return Y(400,j);let{url:q,error:P}=VO(H.callback);if(P)return Y(400,P);let N=!!(L&&L.length);if(N&&z)return Y(400,IK);let D=N||z,U=q??"",M=ZO.has(_)?_:"info",T=K||W,x=J.sanitizeSessionName(W),w=J.chatIdForSession(x);if(!w)return B(`notify: project "${W}" (sanitized "${x}") has no chat binding → 404`),Y(404,`project "${W}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let b=Array.isArray(H.images)?H.images:[],v=[];for(let l of b){let A=String(l??"").trim();if(!A)continue;let k=await J.uploadImageKey(A);v.push({key:k??"",src:A})}let C=D?`nf_${$O()}`:"",f=gK({title:T,text:G,level:M,images:v,buttons:L,allowReply:z,notifyId:C}),m=await J.sendCard(w,f);if(!m)return B(`notify: sendCard failed → 502 (project="${W}" chat=${w.slice(0,8)}…)`),Y(502,"feishu sendCard failed (see daemon log)");if(D&&C){let l={notifyId:C,callbackUrl:U,chatId:w,messageId:m,project:W,title:T,text:G,level:M,imageKeys:v,buttons:L,allowReply:z,createdAt:Date.now()};FW(l)}B(`notify: → ${W} (${w.slice(0,8)}…) level=${M} bytes=${G.length} images=${v.length} buttons=${L?.length??0} allowReply=${z} push=${D&&!!U?1:0} msg=${m}`),V(200,{ok:!0,chat_id:w,message_id:m,...C?{notify_id:C}:{}})}function W2($,Z){return gK({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var ZO,JO,QO,fK=64,IK='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var l5=O(()=>{h();r();C0();t9();ZO=new Set(["info","warn","error"]),JO=new Set(["default","primary","danger"]),QO=/^[A-Za-z0-9_-]{1,64}$/});var uK=HY((Nv,cK)=>{var{readFileSync:XO,rmSync:HO}=_2("node:fs"),{homedir:pK}=_2("node:os"),{join:V3}=_2("node:path"),{managedClaudePluginDir:zO}=Q7();function WO($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Q=Z??[V3(pK(),".codex","skills"),V3(pK(),".claude","skills"),V3(zO(),"skills")],Y=[];for(let V of Q){let X=V3(V,$),H=V3(X,"SKILL.md"),z;try{z=XO(H,"utf8")}catch(K){if(K.code==="ENOENT")continue;let _=Error(`skill: obsolete removal failed (${H}): ${K}`,{cause:K});J(_.message),Y.push(_);continue}let W=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(z)?.[1],G=/^name:[ \t]*(?:"([^"]*)"|'([^']*)'|([^\s#]+))[ \t]*$/m.exec(W??"");if(!G||(G[1]??G[2]??G[3])!==$){J(`skill: obsolete path preserved because ownership is unclear ${H}`);continue}try{HO(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let _=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(_.message),Y.push(_)}}if(Y.length)throw AggregateError(Y,`Failed to remove obsolete Skill ${$}`)}cK.exports={removeManagedSkill:WO}});import{existsSync as dK,readFileSync as iK}from"node:fs";import{homedir as lK}from"node:os";import{join as X3}from"node:path";function d5($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[X3(lK(),".codex","skills"),X3(lK(),".claude","skills")];for(let Q of J){let Y=X3(Q,$.name,"SKILL.md");try{let V=dK(Y)?iK(Y,"utf8"):null;if(V===$.body)continue;l0(Y,$.body),B(`skill: ${V===null?"installed":"updated"} ${Y}`)}catch(V){B(`skill: sync failed (${Y}): ${V}`)}}if(!Z)GO($,L2)}function GO($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=X3(Z,".claude-plugin","plugin.json"),Q=X3(Z,"skills",$.name,"SKILL.md"),Y=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
279
+ `;for(let[V,X]of[[J,Y],[Q,$.body]])try{let H=dK(V)?iK(V,"utf8"):null;if(H===X)continue;l0(V,X),B(`skill: ${H===null?"installed":"updated"} ${V}`)}catch(H){B(`skill: Claude plugin sync failed (${V}): ${H}`)}}function i5($,Z){nK.removeManagedSkill($,Z,B)}var nK;var n5=O(()=>{h();x0();V0();nK=XY(uK(),1)});function KO($){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`---
280
+ name: ${aK}
280
281
  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.")}
281
282
  ---
282
283
 
@@ -533,18 +534,18 @@ is the script's acknowledgement, distinct from the user's response.
533
534
  Hand-edits will be overwritten — set
534
535
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
535
536
  to maintain the file yourself.
536
- `}function SK(){w7({name:xK,body:IA(v.notify.port)})}var xK="feishu-notify";var CK=O(()=>{S0();f7()});import{randomUUID as gA}from"node:crypto";function bK($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,H)=>{if(!V)return"通知已过期或已移除";if(!H)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(X4(V.notifyId))return"通知正在处理中";return null},Y=async(V,X)=>{if($.log(`notify-reply: ${X}`),!await $.sendText(V,`❌ ${X}`))throw Error(`通知回复错误提示发送失败: ${X}`)},Q=async(V,X,H,z)=>{try{await $.updateCard(X,H)}catch(G){await Y(V.chatId,`${z},卡片更新失败:${Z(G)}`)}};return{async recover(V){let X=V.replyState;if(!X||!V.unknownAt)return;let H={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Q(V,X.promptMessageId,B1(V,X,H),"回复送达状态未知"),await Q(V,V.messageId,J2(V,H),"回复送达状态未知")},async open(V,X,H){let z=h$(V),G=J(z,X,H);if(G||!z)return{ok:!1,message:G};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let W=IJ(z.chatId);if(W.some((K)=>K.replyState?.status==="sending"||X4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};I9(V);try{for(let L of W){let j={...L.replyState,status:"cancelled",cancelReason:"switched"};z4(L.notifyId,j),await Q(L,j.promptMessageId,B1(L,j),"已放弃上一条回复并切换通知")}let K={id:gA(),openId:H,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,B1(z,K));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};K.promptMessageId=_;try{z4(V,K)}catch(L){let j=`等待输入状态保存失败,未开始接收回复:${Z(L)}`;return await Q(z,_,B1(z,K,{status:"failed",detail:j}),j),{ok:!1,message:j,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{g9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,X,H,z){let G=h$(V),W=J(G,H,z);if(W||!G)return{ok:!1,message:W};let K=G.replyState;if(!K||K.id!==X||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...K,status:"cancelled"};return z4(V,_),$.onWaitingChanged(G.chatId),await Q(G,K.promptMessageId,B1(G,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:H,messageId:z,text:G,createTime:W}=V;if(!H||!z||!G.trim())return!1;if(QG(X,z))return!0;let K=m9(X,H);if(!K?.replyState)return!1;let _=K.replyState;if(W>0&&W<_.openedAt)return!1;if(_.status!=="waiting"||X4(K.notifyId))return await Y(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let L={text:G,message_id:z,prompt_message_id:_.promptMessageId},j={..._,status:"sending",response:L};I9(K.notifyId);try{try{z4(K.notifyId,j)}catch(D){return await Y(X,`回复保存失败,尚未回传,请重新输入:${Z(D)}`),!0}let q;try{if(await $.updateCard(_.promptMessageId,B1(K,j)),K.callbackUrl)q=await $.dispatch(K,L,H);else p9(K.notifyId,void 0,H),q={ok:!0,detail:"已记录"}}catch(D){q={ok:!1,detail:Z(D)}}let F;if(q.ok){let D=K.callbackUrl?H7(K.notifyId,void 0,H):{state:"complete"};F={kind:"text",text:G,operatorOpenId:H,status:D.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...D.state==="unknown"?{detail:D.detail}:{reply:q.reply}}}else{F={kind:"text",text:G,operatorOpenId:H,status:"failed",detail:q.detail};try{z4(K.notifyId,{...j,status:"failed",error:q.detail})}catch(D){let U=`${q.detail};失败状态保存失败:${Z(D)}`;try{gJ(K.notifyId,void 0,H,U)}catch(A){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(A)}`)}F={...F,status:"unknown",detail:U}}}let R=F.status==="delivered"?"回复已送达":F.status==="done"?"回复已记录":F.status==="unknown"?`回复送达状态未知:${F.detail}`:`回复未送达:${F.detail}`;return await Q(K,_.promptMessageId,B1(K,j,F),R),await Q(K,K.messageId,J2(K,F),R),$.log(`notify-reply: notify_id=${K.notifyId} status=${F.status}`),!0}finally{g9(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var kK=O(()=>{c9();y7()});function yK($){let Z=wY($,"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((G)=>G.trim()).filter(Boolean))],Q=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=F4(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 X=hK(Z.prompt,'agent run requires "prompt"'),H=F4(Z.effort),z=vK(Z);return{identityIds:Y,description:D4(Z.description),prompt:X,...H?{effort:H}:{},...V?{sessionId:V}:{},...z!==void 0?{workDir:z}:{}}}function wK($){let Z=wY($,"agent follow-up request"),J=hK(Z.prompt,'agent follow-up requires "prompt"'),Y=F4(Z.identity_id??Z.identityId),Q=F4(Z.effort),V=vK(Z);return{description:D4(Z.description),prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{},...V!==void 0?{workDir:V}:{}}}function yY($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function vK($){if($.work_dir!==void 0&&$.workDir!==void 0&&$.work_dir!==$.workDir)throw Error("conflicting agent work_dir and workDir");let Z=$.work_dir!==void 0?$.work_dir:$.workDir;return Z===void 0?void 0:yY(Z)}function D4($){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 fK($){let Z=wY($,"agent answer request"),J=F4(Z.identity_id??Z.identityId),Y=F4(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,X]of Object.entries(Z.answers)){if(!V.trim())throw Error("agent answer contains an empty question key");Q[V]=String(X)}if(Object.keys(Q).length===0)throw Error("agent answer requires at least one answer");return{requestId:Y,answers:Q,...J?{identityId:J}:{}}}function wY($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function hK($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function F4($){return(typeof $==="string"?$.trim():"")||void 0}function mA(){return["---",`name: ${IK}`,`description: ${JSON.stringify("Main Agents can delegate tasks to configured models or Agents through Lodestar, including their own model or Agent, and continue the same work across multiple turns. Delegated Agents and subagents must not use this Skill or delegate further.")}`,"---","","# 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.","","## Choosing a delegation method","","- The main Agent chooses between native Agent/subagent capabilities and"," `lodestar-agent` based on the task and available capabilities.","- Both methods are allowed when calling your own model or Agent.","","## Required workflow","","1. When using Lodestar, 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 identities, pass them 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","```","","### Working directory","","New tasks default to the main Agent working directory, even if the calling","shell has changed directory. Use `--workdir <path>` to select an existing","subdirectory. Relative paths are resolved from the main Agent directory;","absolute paths are also accepted within that directory. Symlinks are resolved","and paths outside the main directory, missing paths and files are rejected.","All identities in one run use the same directory; use separate runs for different directories.","","```bash","# desc: 在主 Agent 工作目录的子目录中执行任务","lodestar-agent run --identity '<identity-id>' --description '检查应用代码' --workdir 'packages/app' --prompt 'Inspect the application and report the results.'","```","","`run --session` and `follow-up` retain the original task directory. Omit","`--workdir` when continuing, or supply a path resolving to that same directory;","changing directories requires a new task. Results report `Work directory:`","(JSON: `work_dir`). The HTTP API accepts `work_dir` on run/follow-up requests.","","## 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(`
537
- `)}function mK(){v7("lodestar-consult"),w7({name:IK,body:mA()})}var IK="lodestar-agent",gK;var vY=O(()=>{f7();gK=["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(`
538
- `)});function pK($){let Z=V0($.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}=$9({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,gK].filter(Boolean).join(`
537
+ `}function oK(){d5({name:aK,body:KO(g.notify.port)})}var aK="feishu-notify";var sK=O(()=>{S0();n5()});import{randomUUID as BO}from"node:crypto";function tK($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,H)=>{if(!V)return"通知已过期或已移除";if(!H)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(B4(V.notifyId))return"通知正在处理中";return null},Q=async(V,X)=>{if($.log(`notify-reply: ${X}`),!await $.sendText(V,`❌ ${X}`))throw Error(`通知回复错误提示发送失败: ${X}`)},Y=async(V,X,H,z)=>{try{await $.updateCard(X,H)}catch(W){await Q(V.chatId,`${z},卡片更新失败:${Z(W)}`)}};return{async recover(V){let X=V.replyState;if(!X||!V.unknownAt)return;let H={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Y(V,X.promptMessageId,A1(V,X,H),"回复送达状态未知"),await Y(V,V.messageId,W2(V,H),"回复送达状态未知")},async open(V,X,H){let z=d$(V),W=J(z,X,H);if(W||!z)return{ok:!1,message:W};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=oJ(z.chatId);if(G.some((K)=>K.replyState?.status==="sending"||B4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};n9(V);try{for(let L of G){let j={...L.replyState,status:"cancelled",cancelReason:"switched"};j4(L.notifyId,j),await Y(L,j.promptMessageId,A1(L,j),"已放弃上一条回复并切换通知")}let K={id:BO(),openId:H,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_=await $.sendCard(z.chatId,A1(z,K));if(!_)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};K.promptMessageId=_;try{j4(V,K)}catch(L){let j=`等待输入状态保存失败,未开始接收回复:${Z(L)}`;return await Y(z,_,A1(z,K,{status:"failed",detail:j}),j),{ok:!1,message:j,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{a9(V),$.onWaitingChanged(z.chatId)}},async cancel(V,X,H,z){let W=d$(V),G=J(W,H,z);if(G||!W)return{ok:!1,message:G};let K=W.replyState;if(!K||K.id!==X||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...K,status:"cancelled"};return j4(V,_),$.onWaitingChanged(W.chatId),await Y(W,K.promptMessageId,A1(W,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:H,messageId:z,text:W,createTime:G}=V;if(!H||!z||!W.trim())return!1;if(PW(X,z))return!0;let K=o9(X,H);if(!K?.replyState)return!1;let _=K.replyState;if(G>0&&G<_.openedAt)return!1;if(_.status!=="waiting"||B4(K.notifyId))return await Q(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let L={text:W,message_id:z,prompt_message_id:_.promptMessageId},j={..._,status:"sending",response:L};n9(K.notifyId);try{try{j4(K.notifyId,j)}catch(D){return await Q(X,`回复保存失败,尚未回传,请重新输入:${Z(D)}`),!0}let q;try{if(await $.updateCard(_.promptMessageId,A1(K,j)),K.callbackUrl)q=await $.dispatch(K,L,H);else s9(K.notifyId,void 0,H),q={ok:!0,detail:"已记录"}}catch(D){q={ok:!1,detail:Z(D)}}let P;if(q.ok){let D=K.callbackUrl?P5(K.notifyId,void 0,H):{state:"complete"};P={kind:"text",text:W,operatorOpenId:H,status:D.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...D.state==="unknown"?{detail:D.detail}:{reply:q.reply}}}else{P={kind:"text",text:W,operatorOpenId:H,status:"failed",detail:q.detail};try{j4(K.notifyId,{...j,status:"failed",error:q.detail})}catch(D){let U=`${q.detail};失败状态保存失败:${Z(D)}`;try{sJ(K.notifyId,void 0,H,U)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}P={...P,status:"unknown",detail:U}}}let N=P.status==="delivered"?"回复已送达":P.status==="done"?"回复已记录":P.status==="unknown"?`回复送达状态未知:${P.detail}`:`回复未送达:${P.detail}`;return await Y(K,_.promptMessageId,A1(K,j,P),N),await Y(K,K.messageId,W2(K,P),N),$.log(`notify-reply: notify_id=${K.notifyId} status=${P.status}`),!0}finally{a9(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var rK=O(()=>{t9();l5()});function eK($){let Z=nQ($,"agent run request"),J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Q=[...new Set(J.map((W)=>W.trim()).filter(Boolean))],Y=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=N4(Y);if(Y!==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&&Q.length>1)throw Error("agent session continuation accepts at most one identity_id");if(!V&&Q.length===0)throw Error("agent run requires at least one identity_id");if(Q.length>64)throw Error("agent run supports at most 64 identities");let X=QB(Z.prompt,'agent run requires "prompt"'),H=N4(Z.effort),z=ZB(Z);return{identityIds:Q,description:R4(Z.description),prompt:X,...H?{effort:H}:{},...V?{sessionId:V}:{},...z!==void 0?{workDir:z}:{}}}function $B($){let Z=nQ($,"agent follow-up request"),J=QB(Z.prompt,'agent follow-up requires "prompt"'),Q=N4(Z.identity_id??Z.identityId),Y=N4(Z.effort),V=ZB(Z);return{description:R4(Z.description),prompt:J,...Q?{identityId:Q}:{},...Y?{effort:Y}:{},...V!==void 0?{workDir:V}:{}}}function iQ($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function ZB($){if($.work_dir!==void 0&&$.workDir!==void 0&&$.work_dir!==$.workDir)throw Error("conflicting agent work_dir and workDir");let Z=$.work_dir!==void 0?$.work_dir:$.workDir;return Z===void 0?void 0:iQ(Z)}function R4($){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 JB($){let Z=nQ($,"agent answer request"),J=N4(Z.identity_id??Z.identityId),Q=N4(Z.request_id??Z.requestId);if(!Q)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 Y={};for(let[V,X]of Object.entries(Z.answers)){if(!V.trim())throw Error("agent answer contains an empty question key");Y[V]=String(X)}if(Object.keys(Y).length===0)throw Error("agent answer requires at least one answer");return{requestId:Q,answers:Y,...J?{identityId:J}:{}}}function nQ($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function QB($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function N4($){return(typeof $==="string"?$.trim():"")||void 0}function _O(){return["---",`name: ${YB}`,`description: ${JSON.stringify("Main Agents can delegate tasks to configured models or Agents through Lodestar, including their own model or Agent, and continue the same work across multiple turns. Delegated Agents and subagents must not use this Skill or delegate further.")}`,"---","","# 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.","","## Choosing a delegation method","","- The main Agent chooses between native Agent/subagent capabilities and"," `lodestar-agent` based on the task and available capabilities.","- Both methods are allowed when calling your own model or Agent.","","## Required workflow","","1. When using Lodestar, 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 identities, pass them 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","```","","### Working directory","","New tasks default to the main Agent working directory, even if the calling","shell has changed directory. Use `--workdir <path>` to select an existing","subdirectory. Relative paths are resolved from the main Agent directory;","absolute paths are also accepted within that directory. Symlinks are resolved","and paths outside the main directory, missing paths and files are rejected.","All identities in one run use the same directory; use separate runs for different directories.","","```bash","# desc: 在主 Agent 工作目录的子目录中执行任务","lodestar-agent run --identity '<identity-id>' --description '检查应用代码' --workdir 'packages/app' --prompt 'Inspect the application and report the results.'","```","","`run --session` and `follow-up` retain the original task directory. Omit","`--workdir` when continuing, or supply a path resolving to that same directory;","changing directories requires a new task. Results report `Work directory:`","(JSON: `work_dir`). The HTTP API accepts `work_dir` on run/follow-up requests.","","## 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(`
538
+ `)}function XB(){i5("lodestar-consult"),d5({name:YB,body:_O()})}var YB="lodestar-agent",VB;var aQ=O(()=>{n5();VB=["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(`
539
+ `)});function HB($){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:Q}=H9({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,VB].filter(Boolean).join(`
539
540
 
540
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return pA(Y,$.prompt,$.callbacks)}function pA($,Z,J={},Y=mQ){let Q=[],V=null,X=!1,H=null,z=null,G=[],W,K,_=Date.now(),L=new Promise((M,b)=>{W=M,K=b}),j=(M)=>{if(!M)return null;try{return Y($.provider,M),J.onSession?.(M),null}catch(b){return b instanceof Error?b:Error(String(b))}},q=()=>{if($.off("assistant_text",R),$.off("tool_use",U),$.off("tool_result",A),$.off("subagent_step",x),$.off("can_use_tool",S),$.off("hook_callback",h),$.off("init",y),!$.isAlive())$.off("error",g);$.off("turn_retry",I),$.off("codex_account_changed",C),$.off("result",c),$.off("exit",l)},F=(M,b)=>{if(H)return H;return X=!0,G.length=0,H=Promise.resolve().then(async()=>{let d=j($.sessionId);try{await $.kill(3000)}catch(L1){z=L1 instanceof Error?L1:Error(String(L1))}q();let a=[M,d,z].filter((L1)=>!!L1),B0=a.length>1?AggregateError(a,a.map((L1)=>L1.message).join("; ")):a[0];if(B0){K(new r9(B0,Q.join("").trim(),$.sessionId));return}let N4=$.sessionId;if(!N4){K(new r9(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let $3=Q.join("").trim(),V2=lA(b?.checkpoint,$);W({output:$3,outputTruncated:!1,sessionId:N4,...V2?{checkpointId:V2}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),H},R=(M)=>{if(X||M?.parentToolUseId||typeof M?.text!=="string")return;Q.push(M.text)},D=(M)=>{if(X)return;try{J.onProgress?.(M)}catch(b){F(b instanceof Error?b:Error(String(b)))}},U=(M)=>D({at:new Date().toISOString(),phase:"started",tool:String(M?.name??"tool"),detail:""}),A=(M)=>D({at:new Date().toISOString(),phase:"completed",tool:M?.is_error?"tool error":"tool result",detail:""}),x=(M)=>D({at:new Date().toISOString(),phase:M?.phase??"info",tool:String(M?.tool??"subagent"),detail:""}),S=(M)=>{if(X)return;if(M.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(M.request_id,"allow",{updatedInput:M.input??{}})}catch(d){F(d instanceof Error?d:Error(String(d)))}return}let b;try{b=cA(M)}catch(d){F(d instanceof Error?d:Error(String(d)));return}if(G.some((d)=>d.request.requestId===b.requestId))return;G.push({request:b,originalInput:M.input??{}});try{if(G.length===1)J.onNeedsInput?.(b)}catch(d){F(d instanceof Error?d:Error(String(d)))}},h=(M)=>{if(X)return;try{$.sendHookResponse(String(M.request_id),{})}catch(b){F(b instanceof Error?b:Error(String(b)))}},y=(M)=>{let b=j(M?.session_id??$.sessionId);if(b)F(b)},g=(M)=>{V=M instanceof Error?M:Error(String(M))},C=(M)=>{if(X)return;try{J.onCodexAccount?.(M.accountId)}catch(b){F(b instanceof Error?b:Error(String(b)))}if(M.diagnostics.length)D({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:M.diagnostics.join(";")})},I=(M)=>{D({at:new Date().toISOString(),phase:"info",tool:M.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:M.phase==="waiting"?`${M.message} · ${M.delayMs/1000}s 后重试 #${M.attempt}`:`正在重试 #${M.attempt}`})},c=(M)=>{let b=M?.is_error?Error(String(M.error??M.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;F(b,M)},l=(M)=>{if(X)return;let b=`code=${M?.code??"null"} signal=${M?.signal??"null"}`;F(V??Error(`delegated agent exited before result (${b})`))};$.on("assistant_text",R),$.on("tool_use",U),$.on("tool_result",A),$.on("subagent_step",x),$.on("can_use_tool",S),$.on("hook_callback",h),$.on("init",y),$.on("error",g),$.on("turn_retry",I),$.on("codex_account_changed",C),$.on("result",c),$.on("exit",l);try{$.sendInitialize(),$.sendUserText(Z)}catch(M){F(M instanceof Error?M:Error(String(M)))}return{done:L,isAlive:()=>$.isAlive(),pendingInput:()=>G[0]?.request??null,answer(M,b){let d=G[0];if(!d)throw Error("delegated agent is not waiting for input");if(d.request.requestId!==M)throw Error(`delegated agent input request mismatch: expected ${d.request.requestId}`);if($.sendPermissionResponse(M,"allow",{updatedInput:{...d.originalInput,answers:b}}),G.shift(),G[0])J.onNeedsInput?.(G[0].request)},async cancel(M="delegated agent cancelled"){let b=X;if(await F(Error(M)),await L.catch(()=>{}),b){if($.isAlive())await $.kill(3000);z=null,q()}if(z)throw z}}}function cA($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,V)=>uA(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 uA($,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((X)=>{if(typeof X==="string")return{label:X};let H=X&&typeof X==="object"?X:{};return{label:String(H.label??H.value??""),...H.description?{description:String(H.description)}:{}}}).filter((X)=>X.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:V}}function lA($,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 r9;var cK=O(()=>{T6();w4();Z0();vY();r9=class r9 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as dA,randomBytes as iA,randomUUID as nA}from"node:crypto";import{existsSync as aA,readdirSync as oA,readFileSync as $B,realpathSync as uK,statSync as sA}from"node:fs";import{isAbsolute as tA,join as I7,relative as rA,resolve as eA,sep as $O}from"node:path";class IY{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($=ZO){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(dK);if(D4(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,workDir:Z.workDir})}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(dK);D4(J.description);let Y=this.requireMutableDescendant($,Z);if(!M4(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=tK(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=h7($.session.workDir,Y.snapshot.workDir);if(Y.snapshot.sessionWorkDir!==void 0&&V!==Y.snapshot.workDir)throw Error("agent work_dir changed since the original run");if(J.workDir!==void 0&&h7($.session.workDir,J.workDir)!==V)throw Error("agent session continuation must use its original work_dir");let X=J.effort??Q.effort,H=this.reserveCapacity($,1),z;try{return z=this.reserveNativeSession(Q),await this.createRun($.session,{identityIds:[Q.identityId],description:J.description,prompt:J.prompt,effort:X,workDir:V},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Q})}finally{z?.(),H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=tK(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 X=V.pendingInput();if(Q.status=X?"needs_input":"running",X)Q.pendingInput=X;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)));hY(Q)}async shutdown($){let Z=new Set([...this.runs.values()].map((X)=>`${X.snapshot.sessionName}\x00${X.snapshot.chatId}`));for(let X of Z){let[H,z]=X.split("\x00");this.bumpCancellationEpoch(H,z)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Y=await Promise.allSettled(J.map((X)=>this.cancelTree(X,$))),Q=[...this.runs.values()].flatMap((X)=>[...X.handles.values()]),V=Y.some((X)=>X.status==="rejected")?[]:await Promise.allSettled(Q.map((X)=>X.cancel($)));hY([...Y,...V]);for(let X of new Set([...this.runs.values()].map((H)=>H.snapshot.chatId)))await this.presentation.closeChat(X)}async createRun($,Z,J){let Y=h7($.workDir,Z.workDir),Q;if(J.parentRunId){if(Q=this.runs.get(J.parentRunId),!Q)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Q,$)}let V=$.codexAccountId(),X=this.deps.getCatalog(V),H=Z.identityIds.map((L)=>{let j=X.identities.find((F)=>F.id===L);if(!j)throw Error(`agent identity not found: ${L}`);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}),z=H.map((L)=>JO(L,YO(L,Z.effort),J.resumeWorker?.sessionId)),G=`agent_${nA()}`,W={runId:G,codexAccountId:V,sessionName:$.sessionName,chatId:$.chatId,sessionWorkDir:$.workDir,workDir:Y,prompt:Z.prompt,description:D4(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:z,createdAt:new Date().toISOString()},K={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(L){if(this.runs.set(G,K),J.parentRunId)Q?.children.add(G);let j=`Agent 卡片初始化失败,Agent 未启动: ${h0(L)}`;for(let q of z)q.status="failed",q.error=j;throw await this.finalizeRun(K,"failed",j),await this.deps.sendTextRaw($.chatId,`❌ ${j}`),L}if(this.runs.set(G,K),J.parentRunId)Q?.children.add(G);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){K.cancelled=!0;let L="任务已在启动前取消";for(let j of K.snapshot.workers)j.status="cancelled",j.error=L,j.finishedAt=new Date().toISOString();return this.persist(K),await Promise.all(K.snapshot.workers.map((j)=>this.updateWorkerCard(K,j))),await this.finalizeRun(K,"cancelled",L),this.readSnapshot(K)}this.persist(K);for(let L of H){let j=J.resumeWorker?.sessionId;this.executeWorker(K,L,Z.prompt,j).catch((q)=>{B(`agent: run=${G} worker=${L.id} crashed: ${h0(q)}`)})}return this.readSnapshot(K)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((X)=>X.identityId===Z.id);if(await this.acquireSlot(Z,(X)=>{Q.queuedReason=X,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=iA(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;if(this.assertSameSession($,$.session),h7($.session.workDir,$.snapshot.workDir)!==$.snapshot.workDir)throw Error("agent work_dir changed before the worker could start");let X=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Q.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:XO(U9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:z2},hostEnv:{LODESTAR_AGENT_URL:o3(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:V,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(z)=>{if($.cancelled)return;Q.status="needs_input",Q.pendingInput=z,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Q)},onProgress:(z)=>this.recordStep($,Q,z),onCodexAccount:(z)=>{if($.cancelled)return;Q.codexAccountId=z,this.persist($)},onSession:(z)=>{if(Q.sessionId===z)return;Q.sessionId=z,this.persist($)}}});$.handles.set(Z.id,X);let H=await X.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=H.output,Q.outputTruncated=H.outputTruncated,Q.sessionId=H.sessionId,Q.checkpointId=H.checkpointId,Q.durationMs=H.durationMs,Q.usage=H.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(X){if(X instanceof r9){if(Q.output=X.output,Q.outputTruncated=!1,X.sessionId)Q.sessionId=X.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Q.status="failed",Q.error=h0(X),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||e9(Z.status))return;if(Z.steps.push(J),Z.steps.length>nK)Z.steps.splice(0,Z.steps.length-nK);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: ${h0(Y)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${h0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${h0(Y)}`).catch((Q)=>B(`agent: terminal failure delivery failed: ${h0(Q)}`))})}async cancelTree($,Z){let J=!M4($.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((H)=>this.runs.get(H)).filter((H)=>!!H&&this.treeHasActiveRun(H));if(V.length===0)break;let X=await Promise.allSettled(V.map((H)=>this.cancelTree(H,Z)));if(Y.push(...X),X.some((H)=>H.status==="rejected"))break}if(!J){hY(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([V,X])=>{if(await X.cancel(Z),X.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=ZB(Y);throw $.snapshot.status="failed",$.snapshot.error=V.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${V.message}`).catch((X)=>B(`agent: cancellation failure notice failed: ${h0(X)}`)),V}let Q=[];for(let V of $.snapshot.workers)if(!e9(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: ${h0(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Y=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
541
- `),Q=Y.length>3000?`${Y.slice(0,3000)}
542
- …完整错误已保存在任务记录中。`:Y;await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ 委派卡片出现更新错误 · ${$.snapshot.description??$.snapshot.runId}
541
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return jO(Q,$.prompt,$.callbacks)}function jO($,Z,J={},Q=eY){let Y=[],V=null,X=!1,H=null,z=null,W=[],G,K,_=Date.now(),L=new Promise((A,k)=>{G=A,K=k}),j=(A)=>{if(!A)return null;try{return Q($.provider,A),J.onSession?.(A),null}catch(k){return k instanceof Error?k:Error(String(k))}},q=()=>{if($.off("assistant_text",N),$.off("tool_use",U),$.off("tool_result",M),$.off("subagent_step",T),$.off("can_use_tool",x),$.off("hook_callback",w),$.off("init",b),!$.isAlive())$.off("error",v);$.off("turn_retry",f),$.off("codex_account_changed",C),$.off("result",m),$.off("exit",l)},P=(A,k)=>{if(H)return H;return X=!0,W.length=0,H=Promise.resolve().then(async()=>{let d=j($.sessionId);try{await $.kill(3000)}catch(R1){z=R1 instanceof Error?R1:Error(String(R1))}q();let a=[A,d,z].filter((R1)=>!!R1),L0=a.length>1?AggregateError(a,a.map((R1)=>R1.message).join("; ")):a[0];if(L0){K(new H3(L0,Y.join("").trim(),$.sessionId));return}let C4=$.sessionId;if(!C4){K(new H3(Error("delegated agent completed without a native session id"),Y.join("").trim(),null));return}let W3=Y.join("").trim(),B2=FO(k?.checkpoint,$);G({output:W3,outputTruncated:!1,sessionId:C4,...B2?{checkpointId:B2}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),H},N=(A)=>{if(X||A?.parentToolUseId||typeof A?.text!=="string")return;Y.push(A.text)},D=(A)=>{if(X)return;try{J.onProgress?.(A)}catch(k){P(k instanceof Error?k:Error(String(k)))}},U=(A)=>D({at:new Date().toISOString(),phase:"started",tool:String(A?.name??"tool"),detail:""}),M=(A)=>D({at:new Date().toISOString(),phase:"completed",tool:A?.is_error?"tool error":"tool result",detail:""}),T=(A)=>D({at:new Date().toISOString(),phase:A?.phase??"info",tool:String(A?.tool??"subagent"),detail:""}),x=(A)=>{if(X)return;if(A.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(A.request_id,"allow",{updatedInput:A.input??{}})}catch(d){P(d instanceof Error?d:Error(String(d)))}return}let k;try{k=LO(A)}catch(d){P(d instanceof Error?d:Error(String(d)));return}if(W.some((d)=>d.request.requestId===k.requestId))return;W.push({request:k,originalInput:A.input??{}});try{if(W.length===1)J.onNeedsInput?.(k)}catch(d){P(d instanceof Error?d:Error(String(d)))}},w=(A)=>{if(X)return;try{$.sendHookResponse(String(A.request_id),{})}catch(k){P(k instanceof Error?k:Error(String(k)))}},b=(A)=>{let k=j(A?.session_id??$.sessionId);if(k)P(k)},v=(A)=>{V=A instanceof Error?A:Error(String(A))},C=(A)=>{if(X)return;try{J.onCodexAccount?.(A.accountId)}catch(k){P(k instanceof Error?k:Error(String(k)))}if(A.diagnostics.length)D({at:new Date().toISOString(),phase:"info",tool:"账号 MISS",detail:A.diagnostics.join(";")})},f=(A)=>{D({at:new Date().toISOString(),phase:"info",tool:A.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:A.phase==="waiting"?`${A.message} · ${A.delayMs/1000}s 后重试 #${A.attempt}`:`正在重试 #${A.attempt}`})},m=(A)=>{let k=A?.is_error?Error(String(A.error??A.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;P(k,A)},l=(A)=>{if(X)return;let k=`code=${A?.code??"null"} signal=${A?.signal??"null"}`;P(V??Error(`delegated agent exited before result (${k})`))};$.on("assistant_text",N),$.on("tool_use",U),$.on("tool_result",M),$.on("subagent_step",T),$.on("can_use_tool",x),$.on("hook_callback",w),$.on("init",b),$.on("error",v),$.on("turn_retry",f),$.on("codex_account_changed",C),$.on("result",m),$.on("exit",l);try{$.sendInitialize(),$.sendUserText(Z)}catch(A){P(A instanceof Error?A:Error(String(A)))}return{done:L,isAlive:()=>$.isAlive(),pendingInput:()=>W[0]?.request??null,answer(A,k){let d=W[0];if(!d)throw Error("delegated agent is not waiting for input");if(d.request.requestId!==A)throw Error(`delegated agent input request mismatch: expected ${d.request.requestId}`);if($.sendPermissionResponse(A,"allow",{updatedInput:{...d.originalInput,answers:k}}),W.shift(),W[0])J.onNeedsInput?.(W[0].request)},async cancel(A="delegated agent cancelled"){let k=X;if(await P(Error(A)),await L.catch(()=>{}),k){if($.isAlive())await $.kill(3000);z=null,q()}if(z)throw z}}}function LO($){let Z=$.input??{},Q=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Y,V)=>qO(Y,V));if(Q.length===0)throw Error("delegated agent input request contains no questions");return{requestId:String($.request_id),...$.tool_use_id?{toolUseId:$.tool_use_id}:{},questions:Q}}function qO($,Z){let J=$&&typeof $==="object"?$:{question:$},Q=String(J.question??J.prompt??J.title??"").trim();if(!Q)throw Error(`delegated agent input question ${Z+1} is empty`);let Y=String(J.id??Q),V=Array.isArray(J.options)?J.options.map((X)=>{if(typeof X==="string")return{label:X};let H=X&&typeof X==="object"?X:{};return{label:String(H.label??H.value??""),...H.description?{description:String(H.description)}:{}}}).filter((X)=>X.label):[];return{id:Y,...J.header?{header:String(J.header)}:{},question:Q,options:V}}function FO($,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 H3;var zB=O(()=>{v6();g4();e();aQ();H3=class H3 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as PO,randomBytes as DO,randomUUID as UO}from"node:crypto";import{existsSync as MO,readdirSync as AO,readFileSync as UB,realpathSync as WB,statSync as OO}from"node:fs";import{isAbsolute as NO,join as o5,relative as RO,resolve as TO,sep as EO}from"node:path";class tQ{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($=xO){this.deps=$;this.presentation=new I9($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(KB);if(R4(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:Q,worker:Y}=this.requireSessionRun($,Z.sessionId,Z.identityIds[0]);return this.followUp($,Q.snapshot.runId,{identityId:Y.identityId,description:Z.description,prompt:Z.prompt,effort:Z.effort,workDir:Z.workDir})}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(KB);R4(J.description);let Q=this.requireMutableDescendant($,Z);if(!T4(Q.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Y=FB(Q.snapshot,J.identityId);if(Q.handles.get(Y.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Y.sessionId)throw Error(`${Y.identityName} has no resumable native session id`);let V=a5($.session.workDir,Q.snapshot.workDir);if(Q.snapshot.sessionWorkDir!==void 0&&V!==Q.snapshot.workDir)throw Error("agent work_dir changed since the original run");if(J.workDir!==void 0&&a5($.session.workDir,J.workDir)!==V)throw Error("agent session continuation must use its original work_dir");let X=J.effort??Y.effort,H=this.reserveCapacity($,1),z;try{return z=this.reserveNativeSession(Y),await this.createRun($.session,{identityIds:[Y.identityId],description:J.description,prompt:J.prompt,effort:X,workDir:V},{parentRunId:Q.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Y})}finally{z?.(),H()}}async answer($,Z,J){let Q=this.requireMutableDescendant($,Z),Y=FB(Q.snapshot,J.identityId);if(Y.status!=="needs_input"||!Y.pendingInput)throw Error(`${Y.identityName} is not waiting for input`);if(Y.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Y.pendingInput.requestId}`);let V=Q.handles.get(Y.identityId);if(!V)throw Error("waiting agent process is no longer alive; start a follow-up run");V.answer(J.requestId,J.answers);let X=V.pendingInput();if(Y.status=X?"needs_input":"running",X)Y.pendingInput=X;else delete Y.pendingInput;return delete Y.queuedReason,this.refreshNonterminalStatus(Q),this.persist(Q),await this.updateWorkerCard(Q,Y),this.readSnapshot(Q)}getRun($,Z){return this.readSnapshot(this.requireAccessibleRun($,Z))}async cancelRun($,Z,J="agent run cancelled"){let Q=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Q))return!1;return await this.cancelTree(Q,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Q=[...this.runs.values()].filter((V)=>V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Y=await Promise.allSettled(Q.map((V)=>this.cancelTree(V,J)));sQ(Y)}async shutdown($){let Z=new Set([...this.runs.values()].map((X)=>`${X.snapshot.sessionName}\x00${X.snapshot.chatId}`));for(let X of Z){let[H,z]=X.split("\x00");this.bumpCancellationEpoch(H,z)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Q=await Promise.allSettled(J.map((X)=>this.cancelTree(X,$))),Y=[...this.runs.values()].flatMap((X)=>[...X.handles.values()]),V=Q.some((X)=>X.status==="rejected")?[]:await Promise.allSettled(Y.map((X)=>X.cancel($)));sQ([...Q,...V]);for(let X of new Set([...this.runs.values()].map((H)=>H.snapshot.chatId)))await this.presentation.closeChat(X)}async createRun($,Z,J){let Q=a5($.workDir,Z.workDir),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 V=$.codexAccountId(),X=this.deps.getCatalog(V),H=Z.identityIds.map((L)=>{let j=X.identities.find((P)=>P.id===L);if(!j)throw Error(`agent identity not found: ${L}`);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}),z=H.map((L)=>SO(L,CO(L,Z.effort),J.resumeWorker?.sessionId)),W=`agent_${UO()}`,G={runId:W,codexAccountId:V,sessionName:$.sessionName,chatId:$.chatId,sessionWorkDir:$.workDir,workDir:Q,prompt:Z.prompt,description:R4(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:z,createdAt:new Date().toISOString()},K={snapshot:G,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(G)}catch(L){if(this.runs.set(W,K),J.parentRunId)Y?.children.add(W);let j=`Agent 卡片初始化失败,Agent 未启动: ${p0(L)}`;for(let q of z)q.status="failed",q.error=j;throw await this.finalizeRun(K,"failed",j),await this.deps.sendTextRaw($.chatId,`❌ ${j}`),L}if(this.runs.set(W,K),J.parentRunId)Y?.children.add(W);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){K.cancelled=!0;let L="任务已在启动前取消";for(let j of K.snapshot.workers)j.status="cancelled",j.error=L,j.finishedAt=new Date().toISOString();return this.persist(K),await Promise.all(K.snapshot.workers.map((j)=>this.updateWorkerCard(K,j))),await this.finalizeRun(K,"cancelled",L),this.readSnapshot(K)}this.persist(K);for(let L of H){let j=J.resumeWorker?.sessionId;this.executeWorker(K,L,Z.prompt,j).catch((q)=>{B(`agent: run=${W} worker=${L.id} crashed: ${p0(q)}`)})}return this.readSnapshot(K)}async executeWorker($,Z,J,Q){let Y=$.snapshot.workers.find((X)=>X.identityId===Z.id);if(await this.acquireSlot(Z,(X)=>{Y.queuedReason=X,this.persist($),this.updateWorkerCard($,Y)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=DO(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),Y.status="running",Y.startedAt=new Date().toISOString(),delete Y.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Y),$.cancelled)return;if(this.assertSameSession($,$.session),a5($.session.workDir,$.snapshot.workDir)!==$.snapshot.workDir)throw Error("agent work_dir changed before the worker could start");let X=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Y.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Q,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:wO(x9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:L2},hostEnv:{LODESTAR_AGENT_URL:Y8(g.notify.bind,g.notify.port),LODESTAR_AGENT_CAPABILITY:V,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(z)=>{if($.cancelled)return;Y.status="needs_input",Y.pendingInput=z,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Y)},onProgress:(z)=>this.recordStep($,Y,z),onCodexAccount:(z)=>{if($.cancelled)return;Y.codexAccountId=z,this.persist($)},onSession:(z)=>{if(Y.sessionId===z)return;Y.sessionId=z,this.persist($)}}});$.handles.set(Z.id,X);let H=await X.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Y.status="completed",Y.output=H.output,Y.outputTruncated=H.outputTruncated,Y.sessionId=H.sessionId,Y.checkpointId=H.checkpointId,Y.durationMs=H.durationMs,Y.usage=H.usage,Y.finishedAt=new Date().toISOString(),delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}catch(X){if(X instanceof H3){if(Y.output=X.output,Y.outputTruncated=!1,X.sessionId)Y.sessionId=X.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Y.status="failed",Y.error=p0(X),Y.finishedAt=new Date().toISOString(),Y.startedAt)Y.durationMs=Date.now()-Date.parse(Y.startedAt);delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}}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||z3(Z.status))return;if(Z.steps.push(J),Z.steps.length>_B)Z.steps.splice(0,Z.steps.length-_B);if($.progressTimers.has(Z.identityId))return;let Q=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z)},250);$.progressTimers.set(Z.identityId,Q)}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((Q)=>Q.status==="needs_input"||Q.status==="running"||Q.status==="queued")){this.refreshNonterminalStatus($),this.persist($);return}let J=Z.some((Q)=>Q.status==="failed")?"failed":"completed";this.finalizeRun($,J,J==="failed"?"一个或多个 Agent 失败":void 0).catch((Q)=>{$.finalizing=!1,$.finalized=!1,$.snapshot.status="failed",$.snapshot.error=`Agent terminal persistence failed: ${p0(Q)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${p0(Q)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${p0(Q)}`).catch((Y)=>B(`agent: terminal failure delivery failed: ${p0(Y)}`))})}async cancelTree($,Z){let J=!T4($.snapshot.status)&&!$.cancelled||$.handles.size>0,Q=[];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((H)=>this.runs.get(H)).filter((H)=>!!H&&this.treeHasActiveRun(H));if(V.length===0)break;let X=await Promise.allSettled(V.map((H)=>this.cancelTree(H,Z)));if(Q.push(...X),X.some((H)=>H.status==="rejected"))break}if(!J){sQ(Q);return}if(Q.push(...await Promise.allSettled([...$.handles].map(async([V,X])=>{if(await X.cancel(Z),X.isAlive?.())throw Error(`${V}: Agent process is still alive after cancellation`);$.handles.delete(V),this.releaseWorkerSlot($,V)}))),Q.some((V)=>V.status==="rejected")){let V=MB(Q);throw $.snapshot.status="failed",$.snapshot.error=V.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${V.message}`).catch((X)=>B(`agent: cancellation failure notice failed: ${p0(X)}`)),V}let Y=[];for(let V of $.snapshot.workers)if(!z3(V.status))V.status="cancelled",V.error=Z,V.finishedAt=new Date().toISOString(),delete V.pendingInput,Y.push(V);await Promise.all(Y.map((V)=>this.updateWorkerCard($,V))),await this.finalizeRun($,"cancelled",Z)}async finalizeRun($,Z,J){if($.finalized||$.finalizing)return;$.finalizing=!0;for(let Q of[...$.progressTimers.keys()])this.clearProgressTimer($,Q);if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)$.snapshot.error=J;try{await this.presentation.update($.snapshot,!0)}catch(Q){this.recordPresentationError($,`agent card finalization failed: ${p0(Q)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Q=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
542
+ `),Y=Q.length>3000?`${Q.slice(0,3000)}
543
+ …完整错误已保存在任务记录中。`:Q;await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ 委派卡片出现更新错误 · ${$.snapshot.description??$.snapshot.runId}
543
544
  结果已保存,卡片更新期间出现 ${$.snapshot.presentationErrors.length} 个错误:
544
- ${Q}
545
- 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${h0(V)}`))}}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}): ${h0(Y)}`)}finally{if($.snapshot.cardMessageId!==J)this.persist($)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,B(`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=dA("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=rK($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(I7(P1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;QB(Z),this.deps.writeTextArtifact(I7(P1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=rK($.snapshot);if($.artifactsUnloaded)JB(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((X)=>{if(!this.canAccess($,X)||sK(X.snapshot)!==$.session.workDir)return[];return X.snapshot.workers.filter((H)=>H.sessionId===Z&&(!J||H.identityId===J)).map((H)=>({run:X,worker:H}))});if(!Y.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Y.map(({worker:X})=>X.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Q=new Set(Y.map(({run:X})=>X.snapshot.parentRunId)),V=Y.filter(({run:X})=>!Q.has(X.snapshot.runId)).sort((X,H)=>Date.parse(H.run.snapshot.createdAt)-Date.parse(X.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!e9(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||sK($.snapshot)!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!M4($.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((H)=>this.sessionKey(H.snapshot.sessionName,H.snapshot.chatId)===J&&(!M4(H.snapshot.status)||H.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=aK)throw Error(`Session has reached ${aK} active Agent runs`);if([...this.runs.values()].reduce((H,z)=>H+z.snapshot.workers.filter((G)=>!e9(G.status)||z.handles.get(G.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>oK)throw Error(`global Agent worker limit ${oK} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Q+1);let X=!1;return()=>{if(X)return;X=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),eK(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=lK.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=fY||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=lK.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${fY} 个 Agent)`),new Promise((Y)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Y}))}releaseSlot($){this.activeTurns--,eK(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<fY;){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(!M4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!e9(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<=iK)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&M4(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-iK))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function h7($,Z){let J=uK($),Y=uK(eA($,Z===void 0?".":yY(Z))),Q=rA(J,Y);if(Q===".."||Q.startsWith(`..${$O}`)||tA(Q))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!sA(Y).isDirectory())throw Error(`agent work_dir is not a directory: ${Y}`);return Q===""?$:Y}function sK($){return $.sessionWorkDir??$.workDir}function JO($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function YO($,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 tK($,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 M4($){return $==="completed"||$==="failed"||$==="cancelled"}function e9($){return $==="completed"||$==="failed"||$==="cancelled"}function rK($){return JSON.parse(JSON.stringify($))}function QO(){if(!aA(P1))return[];let $=[];for(let Z of oA(P1).filter((J)=>J.endsWith(".json")).sort()){let J=I7(P1,Z),Y;try{Y=JSON.parse($B(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${h0(Q)}`)}if(!VO(Y))throw Error(`agent run artifact is invalid: ${J}`);JB(Y,J),$.push(Y)}return $}function VO($){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"&&(Z.sessionWorkDir===void 0||typeof Z.sessionWorkDir==="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 ZB($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(h0).join("; ")}`)}function hY($){if($.some((Z)=>Z.status==="rejected"))throw ZB($)}function h0($){return $ instanceof Error?$.message:String($)}function XO($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function JB($,Z,J=YB){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 YB($,Z){QB($);try{return $B(I7(P1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${h0(J)}`)}}function QB($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function eK($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var fY=8,lK,dK="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",iK=512,nK=50,aK=64,oK=128,ZO;var VB=O(()=>{PJ();FJ();r();S0();A7();cK();Q0();x0();f();lK=new Map([["openrouter",2]]),ZO={...qJ,getCatalog:i9,startWorker:pK,sendTextRaw:w,writeArtifact:o,writeTextArtifact:g0,readTextArtifact:YB,loadArtifacts:QO}});async function zB($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(W,K)=>{return Z.statusCode=W,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},V=GO($.headers.authorization);if(!V)return Q(401,{error:"missing bearer capability"});let X=HO(Y,V);if(!X)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await y2(),Q(200,WO(await WW(X.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let W=await Y.service.startRun(X,yK(await gY($)));return Q(202,g7(W))}catch(W){return Q(409,{error:HB(W)})}let H=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!H)return Q(405,{error:"unsupported agent endpoint"});let z=zO(H[1]);if(!z)return Q(400,{error:"invalid agent run id encoding"});let G=H[2];try{if(!G&&$.method==="GET")return Q(200,g7(Y.service.getRun(X,z)));if(!G&&$.method==="DELETE"){let W=await Y.service.cancelRun(X,z,"cancelled by agent client");return Q(W?200:409,W?{ok:!0,run_id:z}:{error:"agent run is already terminal",run_id:z})}if(G==="follow-up"&&$.method==="POST"){let W=await Y.service.followUp(X,z,wK(await gY($)));return Q(202,g7(W))}if(G==="answer"&&$.method==="POST"){let W=await Y.service.answer(X,z,fK(await gY($)));return Q(200,g7(W))}}catch(W){return Q(409,{error:HB(W)})}return Q(405,{error:"unsupported agent endpoint"})}function HO($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function zO($){try{return decodeURIComponent($)}catch{return null}}function GO($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function gY($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>XB)throw Error(`request body exceeds ${XB} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function WO($){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 g7($){return{run_id:$.runId,session_name:$.sessionName,work_dir:$.workDir,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 HB($){return $ instanceof Error?$.message:String($)}var XB=4194304;var GB=O(()=>{A7();Z0()});import{chmodSync as KO,existsSync as mY,readFileSync as BB,realpathSync as BO,unlinkSync as _O}from"node:fs";import{homedir as jO}from"node:os";import{basename as LO,dirname as PO,join as _1,resolve as qO}from"node:path";function FO($={}){let Z=BO(qO($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Y=$.exists??mY,Q=PO(Z),V=_1(Q,"src","agent-cli.ts"),X=_1(Q,"lodestar-agent.js"),H=_1(Q,"dist","lodestar-agent.js"),G=/^bun(?:\.exe)?$/i.test(LO(J))?[V,X,H]:[X,H],W=G.find(Y);if(!W)throw Error(`lodestar-agent entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:W}}function _B($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??MO(Z,$.homeDir??jO(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??FO(),V=_1(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${KB(Q.runtime)}" "${KB(Q.entry)}" %*\r
545
+ ${Y}
546
+ 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${p0(V)}`))}}async updateWorkerCard($,Z){if($.finalized)return;let J=$.snapshot.cardMessageId;try{await this.presentation.update($.snapshot)}catch(Q){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${p0(Q)}`)}finally{if($.snapshot.cardMessageId!==J)this.persist($)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,B(`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 Q=PO("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Q}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=PB($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(o5(T1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;NB(Z),this.deps.writeTextArtifact(o5(T1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=PB($.snapshot);if($.artifactsUnloaded)AB(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 Q=[...this.runs.values()].flatMap((X)=>{if(!this.canAccess($,X)||qB(X.snapshot)!==$.session.workDir)return[];return X.snapshot.workers.filter((H)=>H.sessionId===Z&&(!J||H.identityId===J)).map((H)=>({run:X,worker:H}))});if(!Q.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Q.map(({worker:X})=>X.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Y=new Set(Q.map(({run:X})=>X.snapshot.parentRunId)),V=Q.filter(({run:X})=>!Y.has(X.snapshot.runId)).sort((X,H)=>Date.parse(H.run.snapshot.createdAt)-Date.parse(X.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((Q)=>Q.snapshot.workers.some((Y)=>{if(Y.provider!==$.provider||Y.sessionId!==$.sessionId)return!1;let V=Q.handles.get(Y.identityId);return!z3(Y.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||qB($.snapshot)!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!T4($.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),Q=[...this.runs.values()].filter((H)=>this.sessionKey(H.snapshot.sessionName,H.snapshot.chatId)===J&&(!T4(H.snapshot.status)||H.handles.size>0)).length,Y=this.startingRunsBySession.get(J)??0;if(Q+Y>=jB)throw Error(`Session has reached ${jB} active Agent runs`);if([...this.runs.values()].reduce((H,z)=>H+z.snapshot.workers.filter((W)=>!z3(W.status)||z.handles.get(W.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>LB)throw Error(`global Agent worker limit ${LB} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Y+1);let X=!1;return()=>{if(X)return;X=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),DB(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=GB.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=oQ||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=GB.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${oQ} 个 Agent)`),new Promise((Q)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Q}))}releaseSlot($){this.activeTurns--,DB(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<oQ;){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(!T4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!z3(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<=BB)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&T4(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-BB))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function a5($,Z){let J=WB($),Q=WB(TO($,Z===void 0?".":iQ(Z))),Y=RO(J,Q);if(Y===".."||Y.startsWith(`..${EO}`)||NO(Y))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!OO(Q).isDirectory())throw Error(`agent work_dir is not a directory: ${Q}`);return Y===""?$:Q}function qB($){return $.sessionWorkDir??$.workDir}function SO($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function CO($,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 FB($,Z){if(Z){let J=$.workers.find((Q)=>Q.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 T4($){return $==="completed"||$==="failed"||$==="cancelled"}function z3($){return $==="completed"||$==="failed"||$==="cancelled"}function PB($){return JSON.parse(JSON.stringify($))}function bO(){if(!MO(T1))return[];let $=[];for(let Z of AO(T1).filter((J)=>J.endsWith(".json")).sort()){let J=o5(T1,Z),Q;try{Q=JSON.parse(UB(J,"utf8"))}catch(Y){throw Error(`agent run artifact is unreadable (${J}): ${p0(Y)}`)}if(!kO(Q))throw Error(`agent run artifact is invalid: ${J}`);AB(Q,J),$.push(Q)}return $}function kO($){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"&&(Z.sessionWorkDir===void 0||typeof Z.sessionWorkDir==="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 MB($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(p0).join("; ")}`)}function sQ($){if($.some((Z)=>Z.status==="rejected"))throw MB($)}function p0($){return $ instanceof Error?$.message:String($)}function wO($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function AB($,Z,J=OB){if($.promptArtifact)$.prompt=J($.promptArtifact,`prompt for ${Z}`);for(let Q of $.workers)if(Q.outputArtifact)Q.output=J(Q.outputArtifact,`output for ${Z}`)}function OB($,Z){NB($);try{return UB(o5(T1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${p0(J)}`)}}function NB($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function DB($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var oQ=8,GB,KB="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",BB=512,_B=50,jB=64,LB=128,xO;var RB=O(()=>{RJ();EJ();r();S0();w5();zB();V0();x0();h();GB=new Map([["openrouter",2]]),xO={...TJ,getCatalog:Z3,startWorker:HB,sendTextRaw:I,writeArtifact:o,writeTextArtifact:l0,readTextArtifact:OB,loadArtifacts:bO}});async function xB($,Z,J,Q){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Y=(G,K)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},V=fO($.headers.authorization);if(!V)return Y(401,{error:"missing bearer capability"});let X=yO(Q,V);if(!X)return Y(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await g2(),Y(200,hO(await CG(X.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Q.service.startRun(X,eK(await rQ($)));return Y(202,s5(G))}catch(G){return Y(409,{error:EB(G)})}let H=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!H)return Y(405,{error:"unsupported agent endpoint"});let z=vO(H[1]);if(!z)return Y(400,{error:"invalid agent run id encoding"});let W=H[2];try{if(!W&&$.method==="GET")return Y(200,s5(Q.service.getRun(X,z)));if(!W&&$.method==="DELETE"){let G=await Q.service.cancelRun(X,z,"cancelled by agent client");return Y(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 Q.service.followUp(X,z,$B(await rQ($)));return Y(202,s5(G))}if(W==="answer"&&$.method==="POST"){let G=await Q.service.answer(X,z,JB(await rQ($)));return Y(200,s5(G))}}catch(G){return Y(409,{error:EB(G)})}return Y(405,{error:"unsupported agent endpoint"})}function yO($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function vO($){try{return decodeURIComponent($)}catch{return null}}function fO($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function rQ($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>TB)throw Error(`request body exceeds ${TB} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function hO($){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 s5($){return{run_id:$.runId,session_name:$.sessionName,work_dir:$.workDir,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 EB($){return $ instanceof Error?$.message:String($)}var TB=4194304;var SB=O(()=>{w5();e()});import{chmodSync as IO,existsSync as eQ,readFileSync as kB,realpathSync as gO,unlinkSync as mO}from"node:fs";import{homedir as pO}from"node:os";import{basename as cO,dirname as uO,join as O1,resolve as lO}from"node:path";function dO($={}){let Z=gO(lO($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Q=$.exists??eQ,Y=uO(Z),V=O1(Y,"src","agent-cli.ts"),X=O1(Y,"lodestar-agent.js"),H=O1(Y,"dist","lodestar-agent.js"),W=/^bun(?:\.exe)?$/i.test(cO(J))?[V,X,H]:[X,H],G=W.find(Q);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${W.join(", ")}`);return{runtime:J,entry:G}}function wB($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??nO(Z,$.homeDir??pO(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??dO(),V=O1(Q,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${bB(Y.runtime)}" "${bB(Y.entry)}" %*\r
546
547
  `:`#!/bin/sh
547
- exec ${WB(Q.runtime)} ${WB(Q.entry)} "$@"
548
- `,H=mY(V)?BB(V,"utf8"):null;if(H!==X)AQ(V,X),B(`command: ${H===null?"installed":"updated"} ${V}`);else KO(V,448);return UO(J,Y,Z),DO(Y,Z),V}function DO($,Z){let J=_1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!mY(J))return;try{let Y=BB(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}_O(J),B(`command: removed obsolete ${J}`)}catch(Y){B(`command: obsolete removal failed (${J}): ${Y}`)}}function MO($,Z,J){if($==="win32")return _1(J??_1(Z,"AppData","Local"),"Lodestar","bin");return _1(Z,".local","bin")}function UO($,Z,J){let Y=J==="win32"?Object.keys($).find((H)=>H.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",V=$[Y]??"",X=(H)=>J==="win32"?H.toLowerCase():H;if(V.split(Q).some((H)=>X(H)===X(Z)))return;$[Y]=V?`${Z}${Q}${V}`:Z}function WB($){return`'${$.replaceAll("'",`'"'"'`)}'`}function KB($){return $.replaceAll('"','""')}var jB=O(()=>{f();x0()});function LB($,Z,J){return $>0&&Z-$>J}async function PB($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function qB($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function pY($){return typeof $==="string"&&$.length>0?$:void 0}function FB($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=pY(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=pY(J.file_key);if(!Y)return null;let Q=pY(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function DB($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function MB($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class cY{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 p$($){return $ instanceof Error?$.message:String($)}function UB($,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 AB($){let Z=(Q,V)=>{let X=$.registry.get(Q);if(X&&X.sessionName!==V)throw Error(`chat ${Q} is already owned by session "${X.sessionName}", not "${V}"`);if(!X)X=$.createSession(V,Q),$.registry.set(Q,X);return X};return{sessionFor:Z,createTempSession:async(Q)=>{let V;try{if(L0(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(H){let z=p$(H);return $.log(`temp-session: create "${Q.chatName}" failed: ${z}`),{ok:!1,error:z}}let X=async()=>{let H=null;try{if($.registerTempSessionLease(Q.chatName,V.chatId),H=Z(V.chatId,Q.chatName),H.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(H.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${H.workDir}`);if(H.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await H.startForked(Q.launch,{announce:!1}):await H.start({announce:!1})))throw Error(`${H.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let G=p$(z);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${G}`),H)try{await H.stop("临时群启动失败清理",{announce:!1})}catch(K){let _=p$(K);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let W;try{let K=await $.disbandChatForSessionExact(Q.chatName,V.chatId);W=UB(Q.chatName,V.chatId,K)}catch(K){let _=p$(K);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(W),H?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(K){let _=p$(K);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${_}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(H){let z=p$(H);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Q,V)=>{let X=$.chatIdForSession(Q);if(!V||X!==V){let G=`临时群 chat_id 已变化: expected=${V||"-"} bound=${X??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,V)){let G=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}let H=$.registry.get(X);try{if(H)await H.stop("bye 解散",{announce:!1})}catch(G){let W=p$(G);return $.log(`temp-session: stop before disband "${Q}" failed: ${W}`),{ok:!1,error:`${W};无法确认 Session 已停止,未执行删群`}}let z;try{let G=await $.disbandChatForSessionExact(Q,X);z=UB(Q,X,G)}catch(G){let W=p$(G);return $.log(`temp-session: disband "${Q}" failed: ${W}`),{ok:!1,error:`${W};临时群/session 仍保留`}}try{return $.registry.delete(z),H?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(G){let W=p$(G);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${W}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${W}`}}}}}var OB=O(()=>{M1()});var uO={};import*as A4 from"@larksuiteoapi/node-sdk";import{chmodSync as AO,existsSync as lY,mkdirSync as OO,readFileSync as NO,unlinkSync as p7,writeFileSync as RO}from"node:fs";import{dirname as TO}from"node:path";function O4($,Z){if(j1=Math.max(j1,Z),m7)return m7;I0=!0,EB?.(),u$.close();for(let J of F$.values())J.closeModelSettingsChanges();try{xB?.()}catch(J){j1=1,B(`shutdown WebSocket close failed: ${J}`)}try{Q2.persist()}catch(J){B(`shutdown alive marker write failed: ${J}`),j1=1}return m7=(async()=>{B(`${$}: staged shutdown begin sessions=${F$.size}`);try{let J=(async()=>{await MB(()=>[...u$.pending(),...CB]),Q2.freezeForShutdown();let X=await Promise.allSettled([c7.shutdown(`daemon ${$}`),o1.shutdown()]),H=await Promise.allSettled([aJ()]),z=await Promise.allSettled([...F$.values()].map((G)=>G.stop(`daemon ${$}`,{announce:!1})));return[...X,...H,...z]})(),Y=null,Q=new Promise((X)=>{Y=setTimeout(()=>X("deadline"),RB)}),V=await Promise.race([J.then((X)=>{for(let H of X)if(H.status==="rejected")j1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(V==="deadline")j1=1,B(`${$}: shutdown deadline ${RB}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(J){B(`${$}: staged shutdown failed: ${J}`),j1=1}finally{SB(),process.exit(j1)}})(),m7}function dY($){return DB(CB,$)}function bB($,Z="ws"){if(I0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=xO.accept($);if(!Y.accepted)return B(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{B(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function SO(){Q2.persist()}function kB($,Z){return iY.sessionFor($,Z)}async function CO($){return await iY.createTempSession($)}async function bO($,Z){return await iY.disbandTempSession($,Z)}function kO($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let V=Array.isArray($?.content)?$.content:[];for(let X of V){if(!Array.isArray(X))continue;let H=[];for(let G of X){if(!G||typeof G!=="object")continue;switch(G.tag){case"text":{let W=String(G.text??""),K=Array.isArray(G.style)?G.style:[];if(K.includes("bold"))W=`**${W}**`;if(K.includes("italic"))W=`*${W}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))W=`~~${W}~~`;H.push(W);break}case"a":{let W=String(G.href??""),K=String(G.text??W);H.push(`[${K}](${W})`);break}case"at":{let W=String(G.user_name??G.user_id??"");H.push(`@${W}`);break}case"code_inline":H.push(`\`${String(G.text??"")}\``);break;case"hr":H.push("---");break;case"img":if(G.image_key)Z.push(String(G.image_key));break;case"media":if(G.file_key)J.push({key:String(G.file_key),name:G.file_name});break;case"emotion":break;default:if(typeof G.text==="string")H.push(G.text)}}let z=H.join("");if(z.trim())Y.push(z)}return{markdown:Y.join(`
548
+ exec ${CB(Y.runtime)} ${CB(Y.entry)} "$@"
549
+ `,H=eQ(V)?kB(V,"utf8"):null;if(H!==X)vY(V,X),B(`command: ${H===null?"installed":"updated"} ${V}`);else IO(V,448);return aO(J,Q,Z),iO(Q,Z),V}function iO($,Z){let J=O1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!eQ(J))return;try{let Q=kB(J,"utf8");if(!Q.includes("lodestar-consult")&&!Q.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}mO(J),B(`command: removed obsolete ${J}`)}catch(Q){B(`command: obsolete removal failed (${J}): ${Q}`)}}function nO($,Z,J){if($==="win32")return O1(J??O1(Z,"AppData","Local"),"Lodestar","bin");return O1(Z,".local","bin")}function aO($,Z,J){let Q=J==="win32"?Object.keys($).find((H)=>H.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",V=$[Q]??"",X=(H)=>J==="win32"?H.toLowerCase():H;if(V.split(Y).some((H)=>X(H)===X(Z)))return;$[Q]=V?`${Z}${Y}${V}`:Z}function CB($){return`'${$.replaceAll("'",`'"'"'`)}'`}function bB($){return $.replaceAll('"','""')}var yB=O(()=>{h();x0()});function vB($,Z,J){return $>0&&Z-$>J}async function fB($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function hB($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function $Y($){return typeof $==="string"&&$.length>0?$:void 0}function IB($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=$Y(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=$Y(J.file_key);if(!Q)return null;let Y=$Y(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function gB($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function mB($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class ZY{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 Q;try{Q=this.deps.sessionFor(J,Z);let Y=await Q.restoreAfterDaemonRestart();this.deps.log(`revive: "${Z}" ${Y?"restored":"did not start"}`)}catch(Y){this.deps.log(`revive: restore "${Z}" failed: ${Y}`)}finally{if(Q)this.pending.delete(Z);this.persist()}})})).then(()=>{}),this.revival}}function o$($){return $ instanceof Error?$.message:String($)}function pB($,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 cB($){let Z=(Y,V)=>{let X=$.registry.get(Y);if(X&&X.sessionName!==V)throw Error(`chat ${Y} is already owned by session "${X.sessionName}", not "${V}"`);if(!X)X=$.createSession(V,Y),$.registry.set(Y,X);return X};return{sessionFor:Z,createTempSession:async(Y)=>{let V;try{if(F0(Y.launch,Y.routing.provider,Y.workDir),Y.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(V=await $.ensureChatForSession(Y.chatName,Y.userOpenId),!V.created)return{ok:!1,chatId:V.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(H){let z=o$(H);return $.log(`temp-session: create "${Y.chatName}" failed: ${z}`),{ok:!1,error:z}}let X=async()=>{let H=null;try{if($.registerTempSessionLease(Y.chatName,V.chatId),H=Z(V.chatId,Y.chatName),H.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(H.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${H.workDir}`);if(H.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await H.startForked(Y.launch,{announce:!1}):await H.start({announce:!1})))throw Error(`${H.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let W=o$(z);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${W}`),H)try{await H.stop("临时群启动失败清理",{announce:!1})}catch(K){let _=o$(K);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${W};既有群保留,未执行删除`};let G;try{let K=await $.disbandChatForSessionExact(Y.chatName,V.chatId);G=pB(Y.chatName,V.chatId,K)}catch(K){let _=o$(K);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${W};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(G),H?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(K){let _=o$(K);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,error:`${W};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${W};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(H){let z=o$(H);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Y,V)=>{let X=$.chatIdForSession(Y);if(!V||X!==V){let W=`临时群 chat_id 已变化: expected=${V||"-"} bound=${X??"-"}`;return $.log(`temp-session: disband identity rejected "${Y}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}if(!$.hasTempSessionLease(Y,V)){let W=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Y}": ${W}`),{ok:!1,error:`${W};未执行停止或删群`}}let H=$.registry.get(X);try{if(H)await H.stop("bye 解散",{announce:!1})}catch(W){let G=o$(W);return $.log(`temp-session: stop before disband "${Y}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let z;try{let W=await $.disbandChatForSessionExact(Y,X);z=pB(Y,X,W)}catch(W){let G=o$(W);return $.log(`temp-session: disband "${Y}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(z),H?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(W){let G=o$(W);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var uB=O(()=>{C1()});var qN={};import*as x4 from"@larksuiteoapi/node-sdk";import{chmodSync as oO,existsSync as QY,mkdirSync as sO,readFileSync as tO,unlinkSync as r5,writeFileSync as rO}from"node:fs";import{dirname as eO}from"node:path";function S4($,Z){if(N1=Math.max(N1,Z),t5)return t5;c0=!0,nB?.(),t$.close();for(let J of U$.values())J.closeModelSettingsChanges();try{aB?.()}catch(J){N1=1,B(`shutdown WebSocket close failed: ${J}`)}try{K2.persist()}catch(J){B(`shutdown alive marker write failed: ${J}`),N1=1}return t5=(async()=>{B(`${$}: staged shutdown begin sessions=${U$.size}`);try{let J=(async()=>{await mB(()=>[...t$.pending(),...sB]),K2.freezeForShutdown();let X=await Promise.allSettled([e5.shutdown(`daemon ${$}`),J2.shutdown()]),H=await Promise.allSettled([VQ()]),z=await Promise.allSettled([...U$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[...X,...H,...z]})(),Q=null,Y=new Promise((X)=>{Q=setTimeout(()=>X("deadline"),dB)}),V=await Promise.race([J.then((X)=>{for(let H of X)if(H.status==="rejected")N1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),Y]);if(Q)clearTimeout(Q);if(V==="deadline")N1=1,B(`${$}: shutdown deadline ${dB}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(J){B(`${$}: staged shutdown failed: ${J}`),N1=1}finally{oB(),process.exit(N1)}})(),t5}function YY($){return gB(sB,$)}function tB($,Z="ws"){if(c0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=ZN.accept($);if(!Q.accepted)return B(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Q.reason}`),!1;return Q.completion.catch((Y)=>{B(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Y}`)}),!0}function JN(){K2.persist()}function rB($,Z){return VY.sessionFor($,Z)}async function QN($){return await VY.createTempSession($)}async function YN($,Z){return await VY.disbandTempSession($,Z)}function VN($){let Z=[],J=[],Q=[],Y=typeof $?.title==="string"?$.title.trim():"";if(Y)Q.push(`# ${Y}`);let V=Array.isArray($?.content)?$.content:[];for(let X of V){if(!Array.isArray(X))continue;let H=[];for(let W of X){if(!W||typeof W!=="object")continue;switch(W.tag){case"text":{let G=String(W.text??""),K=Array.isArray(W.style)?W.style:[];if(K.includes("bold"))G=`**${G}**`;if(K.includes("italic"))G=`*${G}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))G=`~~${G}~~`;H.push(G);break}case"a":{let G=String(W.href??""),K=String(W.text??G);H.push(`[${K}](${G})`);break}case"at":{let G=String(W.user_name??W.user_id??"");H.push(`@${G}`);break}case"code_inline":H.push(`\`${String(W.text??"")}\``);break;case"hr":H.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")H.push(W.text)}}let z=H.join("");if(z.trim())Q.push(z)}return{markdown:Q.join(`
549
550
 
550
- `),imageKeys:Z,fileKeys:J}}async function wO($,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&&U4.has(V))return;if(V){if(U4.add(V),U4.size>200){let U=[...U4];U4.clear();for(let A of U.slice(-100))U4.add(A)}}let X=Number(J.create_time??0);if(LB(X,Z,yO)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)d0(V,"CrossMark");return}let H=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?z.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{RO(Q3,JSON.stringify({chat_id:H,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${H.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(A){B(`debug: seed context failed: ${A}`)}let U=G.slice(7);z.text=U,J.content=JSON.stringify(z)}let W=W0.get(H);if(!W)await N9(),W=W0.get(H);if(!W)W=await WJ(H)??void 0;if(!W){B(`unknown chat ${H}, dropping message`),await E(H,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=jJ(W);i2(K,H);let _=kB(H,K),L={};try{L=JSON.parse(J.content??"{}")}catch{}let j=J.message_type,q="",F=!1,R=[];if(j==="text")q=(L.text??"").trim();else if(j==="post"){let U=kO(L);F=U.imageKeys.length>0||U.fileKeys.length>0,q=U.markdown.trim();for(let A of U.imageKeys){let x=await R9(J.message_id,A,"image");if(x)R.push(x)}for(let A of U.fileKeys){let x=await R9(J.message_id,A.key,"file",A.name);if(x)R.push(x)}}if(j==="text"&&q){if(await _.runCommand(q,Q,V))return}if((j==="text"||j==="post")&&q&&!F&&await PB({reply:()=>u7.consume({chatId:H,openId:Q,messageId:V??"",text:q,createTime:X,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(q,Q,V??"")}))return;if(j==="text"&&q&&await _.consumeModelCustomMessage(q,Q))return;let D=FB(j,L);if(D){let U=await R9(J.message_id,D.key,D.type,D.name);if(!U){await E(H,qB(j));return}if(R.push(U),!q&&D.displayText)q=D.displayText}if(!q&&R.length===0){B(`drop empty message ${V} type=${j}`);return}if(await _.onMultiMessageInbound(q,R,Q,V??""))return;await _.onUserMessage(q||"(empty)",R,Q,V??"")}function l7($){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 vO($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function H0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function c$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function x$($){let Z=H0($.card?z$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok,$.pending?void 0:$.message);if($.completion)Z.__modelActionCompletion=$.completion;return Z}async function Y2($,Z){if(!$){B(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await w($,Z))B(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function TB($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=l7(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=vO(Z),H=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await r2(V,X);return}catch(L){B(`card-action: ${J} original-card update failed: ${L instanceof Error?L.message:L}`),await Y2(Q,`⚠️ ${Y}已处理,但原卡更新失败。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await Y2(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,G=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Y}已完成`,W=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||z?.type==="error"&&!W;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await Y2(Q,`${K?"❌":"✅"} ${Y}: ${G}`)}async function fO($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await Y2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${l7(J)}失败: ${Y}`)}function yB($){return hO.accept($)}async function IO($){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 X=String(J.notify_id??""),H=h$(X);if(H)$.__cardActionChatId=H.chatId;if(J.kind==="notify_callback")return await gO(J,Y,Q);let z=J.kind==="notify_reply"?await u7.open(X,Y,Q):await u7.cancel(X,String(J.reply_id??""),Y,Q),G=H0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return H?c$(H,G):G}let V=F$.get(Y);if(!V)return H0({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let X=String(J.decision??"");if(!["allow","allow_always","deny"].includes(X))return{toast:{type:"error",content:"无效的权限决定"}};let H=await V.onPermissionDecision(J.request_id,X,Q);return H0({toast:{type:H.ok?X==="deny"?"error":"success":"error",content:H.message}},H.ok)}case"menu":{let X=Number(J.choice??-1);try{if(!Number.isInteger(X)||X<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${X+1})`),H0(z$(Q1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(H){let z=H instanceof Error?H.message:String(H);return H0(z$(Q1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return x$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return x$(X)}case"model_list_open":{let X=String(J.panel_id??""),H=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return x$(await(J.mode==="add"?V.onModelAddOpen(X,H):V.onProviderSelect(H,X)))}case"model_add":case"model_remove":case"model_custom_remove":return x$(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 X=await V.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return x$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return x$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return x$(X)}case"model_effort_select":{let X=await V.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return x$(X)}case"ask":{let X=V.askBlockReason(String(J.tool_use_id??""));if(X)return H0({toast:{type:"error",content:X}},!1);if(J.custom){let G=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",W=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,G,Q);return H0({toast:{type:W?"success":"error",content:W?"已回答":G.trim()?"问题已失效或答案未被接受":"请输入答案"}},W)}let H=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return H0({toast:{type:H?"success":"error",content:H?"已回答":"问题已失效或选项无效"}},H)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return H0(z$(X.card),X.ok)}case"temp_fork_select":{let X=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:z$(Q1({title:"\uD83D\uDD31 会话分叉",message:X.message,ok:X.ok})),X.ok)}case"temp_back_select":{let X=await V.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:z$(Q1({title:"⏪ 会话回滚",message:X.message,ok:X.ok})),X.ok)}case"temp_resume_select":{let X=await V.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(X.replaceCard===!1)return H0({toast:{type:"error",content:X.message}},X.ok);if(!X.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return H0(z$(KZ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return H0(z$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return H0(z$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return H0(z$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (M7(),D7));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return x$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function gO($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=h$(Y);if(!V)return B(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(V.unknownAt)return c$(V,H0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return c$(V,{toast:{type:"info",content:"已处理过"}});if(X4(Y))return c$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return c$(V,H0({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let X=V.buttons.find((G)=>G.id===Q);if(!X)return B(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),c$(V,H0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{p9(V.notifyId,X.id,J)}catch(G){return c$(V,H0({toast:{type:"error",content:`保存反馈结果失败: ${G instanceof Error?G.message:G}`}},!1))}return B(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),c$(V,{...z$(J2(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}I9(V.notifyId);let H=dY(mO(V,X,J));H.catch((G)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let z=H.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return c$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:z})}async function mO($,Z,J){try{let Y=J2($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await r2($.messageId,Y)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${H instanceof Error?H.message:H}`)}let Q=await mJ($,Z,J),V=Q.ok?"complete":"retry",X;if(Q.ok){let H=H7($.notifyId,Z.id,J);if(H.state==="complete")X={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{V="unknown",X={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${H.detail}`);try{await Y2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${H.detail}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${z instanceof Error?z.message:z}`)}}}else X={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Q.detail};try{let H=J2($,X);await r2($.messageId,H)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${H instanceof Error?H.message:H}`);try{await Y2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${H instanceof Error?H.message:H}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),V}finally{g9($.notifyId)}}function uY($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function pO(){if(process.platform==="win32"){B("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){B("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(lY(q1))p7(q1)}catch{}try{Bun.serve({unix:q1,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(!lY(Q3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Q={};try{Q=JSON.parse(NO(Q3,"utf8"))}catch(W){return new Response(`ctx read failed: ${W}`,{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 W=F$.get(Q.chat_id);return W?Response.json(kY(W)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let W=F$.get(Q.chat_id);if(!W)return new Response("debug session not found",{status:404});try{if(typeof Y.message_id!=="string"||!Y.message_id.startsWith("om_"))throw Error("message_id required");let K=typeof Y.value?.panel_id==="string"?Y.value.panel_id.trim():"",_=W.modelPanels.get(K);if(!_?.messageId||_.messageId!==Y.message_id)throw Error("stale or mismatched model panel");let L=await X0.im.v1.message.get({path:{message_id:Y.message_id}});if(L.code!==0)throw Error(`message.get failed: ${L.code} ${L.msg}`);let j=jK(Y,Q,L.data?.items?.[0],v.feishu.app_id,_.messageId);B(`debug: model action ${Y.value.kind} chat=${Q.chat_id.slice(0,8)}…`);let q=yB(j);return await u$.enqueue(Q.chat_id,async()=>{}),Response.json({admission:q,state:kY(W)})}catch(K){return new Response(K instanceof Error?K.message:String(K),{status:400})}}if(Z.pathname!=="/")return new Response("unknown debug endpoint",{status:404});let X=String(Y.text??"");if(!X)return new Response("text required",{status:400});let H=`【自动化测试】:${X}`,z=await E(Q.chat_id,H);if(!z)return new Response("sendText failed — see daemon log",{status:502});let G={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:X}),create_time:String(Date.now())}};if(B(`debug: inject text=${JSON.stringify(X).slice(0,80)} msg_id=${z}`),!bB(G,"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{AO(q1,384)}catch{}B(`debug: inject socket listening at ${q1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function cO(){B(`lodestar-daemon: pid ${process.pid} starting`),Q2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (HY(),cG));if(I0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (Z0(),rV));if(I0)return;if(await Z(),I0)return;if(iZ(),oZ(),sZ(),rZ(),ZJ(),await N9(),I0)return;setInterval(()=>{N9()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (DY(),FY));if(I0)return;try{await J()}catch(M){B(`tasklist deletion reconcile failed: ${M instanceof Error?M.message:M}`)}if(I0)return;let Y,Q=Date.now(),V=0,X=!1,H=null,z=1500,G=90000,W=600000,K=3,_=null,L=0,j="",q=!1,F=(M)=>{B(`[ws] rebuild requested before WS init — ${M}`)},R=(M,b=0,d=!1)=>{if(I0)return;let a=Date.now()+b;if(_){if(q||=d,a>=L){B(`[ws] rebuild already scheduled — ${M}`);return}clearTimeout(_)}L=a,j=M,q=d,_=setTimeout(()=>{let B0=j,N4=q;_=null,L=0,j="",q=!1,F(B0,N4)},b)},D={error:(M)=>B(`[ws-sdk error] ${uY(M)}`),warn:(M)=>{let b=uY(M);if(B(`[ws-sdk warn] ${b}`),b.includes("no pong/inbound"))R("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<W)},info:(M)=>B(`[ws-sdk] ${uY(M)}`),debug:(M)=>{},trace:(M)=>{}},U=new A4.EventDispatcher({}),A=()=>{if(Q=Date.now(),V=0,H)clearTimeout(H),H=null};U.register({"im.message.receive_v1":async(M)=>{if(A(),!bB(M))throw Error("daemon shutdown in progress")}}),U.register({"card.action.trigger":async(M)=>{return A(),yB(M)}});let x=()=>new A4.WSClient({appId:v.feishu.app_id,appSecret:v.feishu.app_secret,loggerLevel:A4.LoggerLevel.info,logger:D,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>h(),onError:(M)=>F(`SDK onError: ${M?.message??M}`)});F=(M,b=!1)=>{if(I0)return;if(X){B(`[ws] rebuild skipped (already rebuilding) — ${M}`);return}if(_)clearTimeout(_),_=null,L=0;X=!0,V++,B(`[ws] rebuild #${V} (fresh WSClient) — ${M}`);let d=Y;try{d?.close({force:!0})}catch(a){B(`[ws] rebuild: old close failed: ${a}`)}if(Y=x(),Y.start({eventDispatcher:U}).catch((a)=>{B(`[ws] rebuild start failed: ${a}`),R(`fresh client start failed: ${a}`,z,b)}),X=!1,b)S()};let S=()=>{if(H)clearTimeout(H);let M=Date.now();H=setTimeout(()=>{if(H=null,Q>=M){V=0;return}if(V>=K){B(`[ws] STILL deaf after ${K} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),V=0;return}F(`verify: no event ${Math.round((Date.now()-M)/1000)}s after rebuild`,!0)},G)},h=()=>{let M=Date.now()-Q<W;B("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${M})`),V=0,R("post-reconnect precaution",z,M)};Y=x();let y=15000,g=2,C=0,I=setInterval(()=>{if(I0)return;let{state:M}=Y.getConnectionStatus();if(M==="connected"){C=0;return}if(M==="failed"||M==="idle"){C=0,F(`watchdog: state=${M}`);return}if(C++,B(`[ws] watchdog: state=${M} (${C}/${g})`),C>=g)C=0,F(`watchdog: stuck in '${M}' ~${Math.round(y*g/1000)}s`)},y);xB=()=>{if(clearInterval(I),_)clearTimeout(_);if(H)clearTimeout(H);Y.close({force:!0})};let c=JG();MK({bind:v.notify.bind,port:v.notify.port,extraHandler:(M,b,d)=>zB(M,b,d,{service:c7,authorizeSession:(a)=>{for(let B0 of F$.values())if(B0.acceptsAgentCapability(a))return B0;return null}})}),_B(),SK(),mK(),v7("lodestar-files");let l=Q2.enqueue();EB=CQ(B,{enabled:v.runtime.agent_auto_update}),Y.start({eventDispatcher:U}).catch((M)=>{B(`[ws] initial start failed: ${M}`),R(`initial start failed: ${M}`,z,!1)}),B(`lodestar-daemon: WS start requested, watching ${W0.size} groups`),pO();for(let M of c)dY(u$.enqueue(M.chatId,()=>u7.recover(M))).catch((b)=>B(`notify-reply recovery failed: ${b instanceof Error?b.message:b}`));await l}var NB=!1,I0=!1,m7=null,j1=0,EB,xB,RB=15000,SB=()=>{if(NB)return;NB=!0;try{Q2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{p7(a0)}catch{}try{p7(q1)}catch{}},F$,c7,u$,Q2,EO,CB,xO,iY,yO=30000,U4,u7,hO;var wB=O(()=>{LY();r();Q$();LK();c9();y7();y7();CK();kK();VB();nJ();B7();GB();vY();f7();jB();S0();f();L2();Q0();Y5();TZ();OB();{let $=V3(a0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(lY(a0))try{p7(a0)}catch{}}OO(TO(a0),{recursive:!0});HQ(a0);process.on("exit",SB);process.on("SIGTERM",()=>{O4("SIGTERM",0)});process.on("SIGINT",()=>{O4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{O4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),O4("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),O4("uncaughtException",1)});F$=new Map,c7=new IY,u$=new F9,Q2=new cY({readMarker:VJ,writeMarker:QJ,sessions:()=>F$.values(),chatIdForSession:m8,sessionFor:kB,actor:u$,isShuttingDown:()=>I0,log:B}),EO=new RZ(30000),CB=new Set,xO=AH({actor:u$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>wO($,Z)});iY=AB({registry:F$,createSession:($,Z)=>{let J=new q$($,Z,{agentCards:c7.presentation,onLifecycleChange:SO,onCreateTempSession:CO,onDisbandTempSession:bO,onCancelAgentRuns:(Y,Q,V)=>c7.cancelSessionRuns(Y,Q,V)});return Q2.transferPending(J),J},ensureChatForSession:HJ,disbandChatForSessionExact:GJ,chatIdForSession:m8,clearSessionConversationState:YJ,registerTempSessionLease:nZ,hasTempSessionLease:aZ,replaceTurnAnchors:l0,runExclusive:($,Z)=>u$.enqueue($,Z),log:B});U4=new Set,u7=bK({sendCard:u,updateCard:r2,sendText:E,dispatch:mJ,onWaitingChanged:($)=>F$.get($)?.refreshPendingAsks(),log:B});hO=OH({actor:u$,deduper:EO,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=h$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(I0)F$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return IO($)},present:TB,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await fO($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await Y2(String($?.context?.open_chat_id??""),`⚠️ ${l7(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?.__modelActionCompletion;if(J)return XV(J,(Q)=>TB($,x$(Q)));let Y=Z?.__cardActionCompletion;return Y&&typeof Y.then==="function"?Y:null},track:($)=>{dY($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${l7(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}})}});cO().catch(($)=>{B(`boot fatal: ${$}`),O4("boot fatal",1)})});Q0();Y5();import{existsSync as vB,unlinkSync as lO}from"node:fs";var D$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function dO(){if(!vB(E0)){if(process.stdin.isTTY){console.log(),console.log(`${D$.bold}${D$.yellow}Lodestar: 未找到配置, 启动安装向导...${D$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (hQ(),fQ));await Z();return}console.error(`${D$.red}Lodestar: 未找到配置 ${E0}${D$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${D$.green}lodestar-setup${D$.reset} 完成首次配置 (或直接运行 ${D$.green}lodestar-daemon${D$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=V3(a0);if($.state==="exit")console.error(`${D$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${D$.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(` • 误判 / 已经死了: 手删 ${a0} 后再跑`),process.exit(1);if(vB(a0))try{lO(a0)}catch{}await Promise.resolve().then(() => (wB(),uO))}dO().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
551
+ `),imageKeys:Z,fileKeys:J}}async function HN($,Z=Date.now()){let J=$?.message;if(!J)return;let Y=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",V=J.message_id;if(V&&E4.has(V))return;if(V){if(E4.add(V),E4.size>200){let U=[...E4];E4.clear();for(let M of U.slice(-100))E4.add(M)}}let X=Number(J.create_time??0);if(vB(X,Z,XN)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)t0(V,"CrossMark");return}let H=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{rO(_3,JSON.stringify({chat_id:H,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${H.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(M){B(`debug: seed context failed: ${M}`)}let U=W.slice(7);z.text=U,J.content=JSON.stringify(z)}let G=B0.get(H);if(!G)await b9(),G=B0.get(H);if(!G)G=await DJ(H)??void 0;if(!G){B(`unknown chat ${H}, dropping message`),await S(H,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=OJ(G);t2(K,H);let _=rB(H,K),L={};try{L=JSON.parse(J.content??"{}")}catch{}let j=J.message_type,q="",P=!1,N=[];if(j==="text")q=(L.text??"").trim();else if(j==="post"){let U=VN(L);P=U.imageKeys.length>0||U.fileKeys.length>0,q=U.markdown.trim();for(let M of U.imageKeys){let T=await k9(J.message_id,M,"image");if(T)N.push(T)}for(let M of U.fileKeys){let T=await k9(J.message_id,M.key,"file",M.name);if(T)N.push(T)}}if(j==="text"&&q){if(await _.runCommand(q,Y,V))return}if((j==="text"||j==="post")&&q&&!P&&await fB({reply:()=>$7.consume({chatId:H,openId:Y,messageId:V??"",text:q,createTime:X,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(q,Y,V??"")}))return;if(j==="text"&&q&&await _.consumeModelCustomMessage(q,Y))return;let D=IB(j,L);if(D){let U=await k9(J.message_id,D.key,D.type,D.name);if(!U){await S(H,hB(j));return}if(N.push(U),!q&&D.displayText)q=D.displayText}if(!q&&N.length===0){B(`drop empty message ${V} type=${j}`);return}if(await _.onMultiMessageInbound(q,N,Y,V??""))return;await _.onUserMessage(q||"(empty)",N,Y,V??"")}function Z7($){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 zN($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function W0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function s$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function y$($){let Z=W0($.card?K$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok,$.pending?void 0:$.message);if($.completion)Z.__modelActionCompletion=$.completion;return Z}async function G2($,Z){if(!$){B(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await I($,Z))B(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function iB($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Q=Z7(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=zN(Z),H=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await Q4(V,X);return}catch(L){B(`card-action: ${J} original-card update failed: ${L instanceof Error?L.message:L}`),await G2(Y,`⚠️ ${Q}已处理,但原卡更新失败。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await G2(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${H}${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():`${Q}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||z?.type==="error"&&!G;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await G2(Y,`${K?"❌":"✅"} ${Q}: ${W}`)}async function WN($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await G2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${Z7(J)}失败: ${Q}`)}function eB($){return GN.accept($)}async function KN($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let X=String(J.notify_id??""),H=d$(X);if(H)$.__cardActionChatId=H.chatId;if(J.kind==="notify_callback")return await BN(J,Q,Y);let z=J.kind==="notify_reply"?await $7.open(X,Q,Y):await $7.cancel(X,String(J.reply_id??""),Q,Y),W=W0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return H?s$(H,W):W}let V=U$.get(Q);if(!V)return W0({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let X=String(J.decision??"");if(!["allow","allow_always","deny"].includes(X))return{toast:{type:"error",content:"无效的权限决定"}};let H=await V.onPermissionDecision(J.request_id,X,Y);return W0({toast:{type:H.ok?X==="deny"?"error":"success":"error",content:H.message}},H.ok)}case"menu":{let X=Number(J.choice??-1);try{if(!Number.isInteger(X)||X<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${X+1})`),W0(K$(_1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(H){let z=H instanceof Error?H.message:String(H);return W0(K$(_1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return y$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return y$(X)}case"model_list_open":{let X=String(J.panel_id??""),H=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return y$(await(J.mode==="add"?V.onModelAddOpen(X,H):V.onProviderSelect(H,X)))}case"model_add":case"model_remove":case"model_custom_remove":return y$(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 X=await V.onModelSelect(String(J.model??""),String(J.panel_id??""),Y,J);return y$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return y$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return y$(X)}case"model_effort_select":{let X=await V.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Y,String(J.provider??""));return y$(X)}case"ask":{let X=V.askBlockReason(String(J.tool_use_id??""));if(X)return W0({toast:{type:"error",content:X}},!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,Y);return W0({toast:{type:G?"success":"error",content:G?"已回答":W.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let H=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return W0({toast:{type:H?"success":"error",content:H?"已回答":"问题已失效或选项无效"}},H)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return W0(K$(X.card),X.ok)}case"temp_fork_select":{let X=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return W0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:K$(_1({title:"\uD83D\uDD31 会话分叉",message:X.message,ok:X.ok})),X.ok)}case"temp_back_select":{let X=await V.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return W0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:K$(_1({title:"⏪ 会话回滚",message:X.message,ok:X.ok})),X.ok)}case"temp_resume_select":{let X=await V.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Y);if(X.replaceCard===!1)return W0({toast:{type:"error",content:X.message}},X.ok);if(!X.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return W0(K$(UZ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return W0(K$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return W0(K$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return W0(K$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (b5(),C5));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return y$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Y))}return{toast:{type:"info",content:"unknown action"}}}async function BN($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=d$(Q);if(!V)return B(`notify-callback: notify_id=${Q.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(V.unknownAt)return s$(V,W0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return s$(V,{toast:{type:"info",content:"已处理过"}});if(B4(Q))return s$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return s$(V,W0({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let X=V.buttons.find((W)=>W.id===Y);if(!X)return B(`notify-callback: notify_id=${Q.slice(0,12)}… unknown button_id="${Y}"`),s$(V,W0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{s9(V.notifyId,X.id,J)}catch(W){return s$(V,W0({toast:{type:"error",content:`保存反馈结果失败: ${W instanceof Error?W.message:W}`}},!1))}return B(`notify-callback: notify_id=${Q.slice(0,12)}… resolved button="${Y}" by=${J.slice(0,8)}… (no callback, pull/display)`),s$(V,{...K$(W2(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}n9(V.notifyId);let H=YY(_N(V,X,J));H.catch((W)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${W instanceof Error?W.message:W}`)});let z=H.then((W)=>W==="retry"?"retry":"complete").catch(()=>"retry");return s$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:z})}async function _N($,Z,J){try{let Q=W2($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await Q4($.messageId,Q)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${H instanceof Error?H.message:H}`)}let Y=await tJ($,Z,J),V=Y.ok?"complete":"retry",X;if(Y.ok){let H=P5($.notifyId,Z.id,J);if(H.state==="complete")X={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Y.reply};else{V="unknown",X={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${H.detail}`);try{await G2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${H.detail}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${z instanceof Error?z.message:z}`)}}}else X={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Y.detail};try{let H=W2($,X);await Q4($.messageId,H)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${H instanceof Error?H.message:H}`);try{await G2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${H instanceof Error?H.message:H}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Y.detail}`} by=${J.slice(0,8)}…`),V}finally{a9($.notifyId)}}function JY($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function jN(){if(process.platform==="win32"){B("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){B("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(QY(E1))r5(E1)}catch{}try{Bun.serve({unix:E1,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(c0)return new Response("daemon shutdown in progress",{status:503});let Q={};if($.method==="POST")try{Q=await $.json()}catch{return new Response("bad json",{status:400})}if(!QY(_3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Y={};try{Y=JSON.parse(tO(_3,"utf8"))}catch(G){return new Response(`ctx read failed: ${G}`,{status:500})}let V=J?Z.searchParams.get("chat_id"):Q.chat_id;if(V!==void 0&&V!==Y.chat_id||Z.pathname!=="/"&&!V)return new Response("explicit debug chat_id must match the seeded context",{status:409});if(J){let G=U$.get(Y.chat_id);return G?Response.json(dQ(G)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let G=U$.get(Y.chat_id);if(!G)return new Response("debug session not found",{status:404});try{if(typeof Q.message_id!=="string"||!Q.message_id.startsWith("om_"))throw Error("message_id required");let K=typeof Q.value?.panel_id==="string"?Q.value.panel_id.trim():"",_=G.modelPanels.get(K);if(!_?.messageId||_.messageId!==Q.message_id)throw Error("stale or mismatched model panel");let L=await z0.im.v1.message.get({path:{message_id:Q.message_id}});if(L.code!==0)throw Error(`message.get failed: ${L.code} ${L.msg}`);let j=yK(Q,Y,L.data?.items?.[0],g.feishu.app_id,_.messageId);B(`debug: model action ${Q.value.kind} chat=${Y.chat_id.slice(0,8)}…`);let q=eB(j);return await t$.enqueue(Y.chat_id,async()=>{}),Response.json({admission:q,state:dQ(G)})}catch(K){return new Response(K instanceof Error?K.message:String(K),{status:400})}}if(Z.pathname!=="/")return new Response("unknown debug endpoint",{status:404});let X=String(Q.text??"");if(!X)return new Response("text required",{status:400});let H=`【自动化测试】:${X}`,z=await S(Y.chat_id,H);if(!z)return new Response("sendText failed — see daemon log",{status:502});let W={sender:{sender_id:{open_id:Y.sender_open_id}},message:{message_id:z,chat_id:Y.chat_id,message_type:"text",content:JSON.stringify({text:X}),create_time:String(Date.now())}};if(B(`debug: inject text=${JSON.stringify(X).slice(0,80)} msg_id=${z}`),!tB(W,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Q.wait_for_handling===!0)await t$.enqueue(Y.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{oO(E1,384)}catch{}B(`debug: inject socket listening at ${E1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function LN(){B(`lodestar-daemon: pid ${process.pid} starting`),K2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (UQ(),zG));if(c0)return;$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (e(),KX));if(c0)return;if(await Z(),c0)return;if(ZJ(),YJ(),VJ(),HJ(),GJ(),await b9(),c0)return;setInterval(()=>{b9()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (kQ(),bQ));if(c0)return;try{await J()}catch(A){B(`tasklist deletion reconcile failed: ${A instanceof Error?A.message:A}`)}if(c0)return;let Q,Y=Date.now(),V=0,X=!1,H=null,z=1500,W=90000,G=600000,K=3,_=null,L=0,j="",q=!1,P=(A)=>{B(`[ws] rebuild requested before WS init — ${A}`)},N=(A,k=0,d=!1)=>{if(c0)return;let a=Date.now()+k;if(_){if(q||=d,a>=L){B(`[ws] rebuild already scheduled — ${A}`);return}clearTimeout(_)}L=a,j=A,q=d,_=setTimeout(()=>{let L0=j,C4=q;_=null,L=0,j="",q=!1,P(L0,C4)},k)},D={error:(A)=>B(`[ws-sdk error] ${JY(A)}`),warn:(A)=>{let k=JY(A);if(B(`[ws-sdk warn] ${k}`),k.includes("no pong/inbound"))N("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Y<G)},info:(A)=>B(`[ws-sdk] ${JY(A)}`),debug:(A)=>{},trace:(A)=>{}},U=new x4.EventDispatcher({}),M=()=>{if(Y=Date.now(),V=0,H)clearTimeout(H),H=null};U.register({"im.message.receive_v1":async(A)=>{if(M(),!tB(A))throw Error("daemon shutdown in progress")}}),U.register({"card.action.trigger":async(A)=>{return M(),eB(A)}});let T=()=>new x4.WSClient({appId:g.feishu.app_id,appSecret:g.feishu.app_secret,loggerLevel:x4.LoggerLevel.info,logger:D,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>w(),onError:(A)=>P(`SDK onError: ${A?.message??A}`)});P=(A,k=!1)=>{if(c0)return;if(X){B(`[ws] rebuild skipped (already rebuilding) — ${A}`);return}if(_)clearTimeout(_),_=null,L=0;X=!0,V++,B(`[ws] rebuild #${V} (fresh WSClient) — ${A}`);let d=Q;try{d?.close({force:!0})}catch(a){B(`[ws] rebuild: old close failed: ${a}`)}if(Q=T(),Q.start({eventDispatcher:U}).catch((a)=>{B(`[ws] rebuild start failed: ${a}`),N(`fresh client start failed: ${a}`,z,k)}),X=!1,k)x()};let x=()=>{if(H)clearTimeout(H);let A=Date.now();H=setTimeout(()=>{if(H=null,Y>=A){V=0;return}if(V>=K){B(`[ws] STILL deaf after ${K} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),V=0;return}P(`verify: no event ${Math.round((Date.now()-A)/1000)}s after rebuild`,!0)},W)},w=()=>{let A=Date.now()-Y<G;B("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${A})`),V=0,N("post-reconnect precaution",z,A)};Q=T();let b=15000,v=2,C=0,f=setInterval(()=>{if(c0)return;let{state:A}=Q.getConnectionStatus();if(A==="connected"){C=0;return}if(A==="failed"||A==="idle"){C=0,P(`watchdog: state=${A}`);return}if(C++,B(`[ws] watchdog: state=${A} (${C}/${v})`),C>=v)C=0,P(`watchdog: stuck in '${A}' ~${Math.round(b*v/1000)}s`)},b);aB=()=>{if(clearInterval(f),_)clearTimeout(_);if(H)clearTimeout(H);Q.close({force:!0})};let m=qW();mK({bind:g.notify.bind,port:g.notify.port,extraHandler:(A,k,d)=>xB(A,k,d,{service:e5,authorizeSession:(a)=>{for(let L0 of U$.values())if(L0.acceptsAgentCapability(a))return L0;return null}})}),wB(),oK(),XB(),i5("lodestar-files");let l=K2.enqueue();nB=uY(B,{enabled:g.runtime.agent_auto_update}),Q.start({eventDispatcher:U}).catch((A)=>{B(`[ws] initial start failed: ${A}`),N(`initial start failed: ${A}`,z,!1)}),B(`lodestar-daemon: WS start requested, watching ${B0.size} groups`),jN();for(let A of m)YY(t$.enqueue(A.chatId,()=>$7.recover(A))).catch((k)=>B(`notify-reply recovery failed: ${k instanceof Error?k.message:k}`));await l}var lB=!1,c0=!1,t5=null,N1=0,nB,aB,dB=15000,oB=()=>{if(lB)return;lB=!0;try{K2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{r5($$)}catch{}try{r5(E1)}catch{}},U$,e5,t$,K2,$N,sB,ZN,VY,XN=30000,E4,$7,GN;var $_=O(()=>{xQ();r();H$();vK();t9();l5();l5();sK();rK();RB();YQ();O5();SB();aQ();n5();yB();S0();h();A2();V0();j7();vZ();uB();{let $=j3($$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(QY($$))try{r5($$)}catch{}}sO(eO($$),{recursive:!0});UY($$);process.on("exit",oB);process.on("SIGTERM",()=>{S4("SIGTERM",0)});process.on("SIGINT",()=>{S4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{S4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),S4("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),S4("uncaughtException",1)});U$=new Map,e5=new tQ,t$=new R9,K2=new ZY({readMarker:jJ,writeMarker:_J,sessions:()=>U$.values(),chatIdForSession:o8,sessionFor:rB,actor:t$,isShuttingDown:()=>c0,log:B}),$N=new yZ(30000),sB=new Set,ZN=vH({actor:t$,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>HN($,Z)});VY=cB({registry:U$,createSession:($,Z)=>{let J=new D$($,Z,{agentCards:e5.presentation,onLifecycleChange:JN,onCreateTempSession:QN,onDisbandTempSession:YN,onCancelAgentRuns:(Q,Y,V)=>e5.cancelSessionRuns(Q,Y,V)});return K2.transferPending(J),J},ensureChatForSession:qJ,disbandChatForSessionExact:PJ,chatIdForSession:o8,clearSessionConversationState:BJ,registerTempSessionLease:JJ,hasTempSessionLease:QJ,replaceTurnAnchors:s0,runExclusive:($,Z)=>t$.enqueue($,Z),log:B});E4=new Set,$7=tK({sendCard:u,updateCard:Q4,sendText:S,dispatch:tJ,onWaitingChanged:($)=>U$.get($)?.refreshPendingAsks(),log:B});GN=fH({actor:t$,deduper:$N,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=d$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(c0)U$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return KN($)},present:iB,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await WN($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await G2(String($?.context?.open_chat_id??""),`⚠️ ${Z7(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?.__modelActionCompletion;if(J)return DV(J,(Y)=>iB($,y$(Y)));let Q=Z?.__cardActionCompletion;return Q&&typeof Q.then==="function"?Q:null},track:($)=>{YY($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${Z7(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}})}});LN().catch(($)=>{B(`boot fatal: ${$}`),S4("boot fatal",1)})});V0();j7();import{existsSync as Z_,unlinkSync as FN}from"node:fs";var M$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function PN(){if(!Z_(E0)){if(process.stdin.isTTY){console.log(),console.log(`${M$.bold}${M$.yellow}Lodestar: 未找到配置, 启动安装向导...${M$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (sY(),oY));await Z();return}console.error(`${M$.red}Lodestar: 未找到配置 ${E0}${M$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${M$.green}lodestar-setup${M$.reset} 完成首次配置 (或直接运行 ${M$.green}lodestar-daemon${M$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=j3($$);if($.state==="exit")console.error(`${M$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${M$.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(` • 误判 / 已经死了: 手删 ${$$} 后再跑`),process.exit(1);if(Z_($$))try{FN($$)}catch{}await Promise.resolve().then(() => ($_(),qN))}PN().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});