@leviyuan/lodestar 0.19.11 → 0.19.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lodestar.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as n_}from"node:module";var I_=Object.create;var{getPrototypeOf:g_,defineProperty:n6,getOwnPropertyNames:m_}=Object;var p_=Object.prototype.hasOwnProperty;function c_($){return this[$]}var l_,u_,XV=($,Z,J)=>{var Q=$!=null&&typeof $==="object";if(Q){var Y=Z?l_??=new WeakMap:u_??=new WeakMap,V=Y.get($);if(V)return V}J=$!=null?I_(g_($)):{};let X=Z||!$||!$.__esModule?n6(J,"default",{value:$,enumerable:!0}):J;for(let z of m_($))if(!p_.call(X,z))n6(X,z,{get:c_.bind($,z),enumerable:!0});if(Q)Y.set($,X);return X};var zV=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var d_=($)=>$;function i_($,Z){this[$]=d_.bind(null,Z)}var r$=($,Z)=>{for(var J in Z)n6($,J,{get:Z[J],enumerable:!0,configurable:!0,set:i_.bind(Z,J)})};var N=($,Z)=>()=>($&&(Z=$($=0)),Z);var l2=n_(import.meta.url);var a6=zV((fT,WV)=>{var{homedir:HV}=l2("node:os"),{join:X9}=l2("node:path");function GV(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return X9(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return X9(process.env.LOCALAPPDATA??X9(HV(),"AppData","Local"),"Lodestar");return X9(HV(),".local","share","lodestar")}function a_(){return X9(GV(),"managed-claude-plugin")}WV.exports={lodestarDataDir:GV,managedClaudePluginDir:a_}});import{homedir as o_}from"node:os";import{join as s}from"node:path";function t_($,Z,J){if($)return $;if(Z)return s(Z,"lodestar");return J}function r_(){if(s_)return s(process.env.APPDATA??s(KV,"AppData","Roaming"),"Lodestar");return s(KV,".config","lodestar")}var l3,KV,s_,o6,t,v0,K$,u2,s6,t6,r6,e6,$5,u3,a1,BV,d3,d2,i2,jV,_V,PV,Z5,LV,qV,J5,Q5,DV,Y5,o1,i3;var H0=N(()=>{l3=XV(a6(),1),KV=o_(),s_=process.platform==="win32";o6=t_(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,r_()),t=l3.lodestarDataDir(),v0=process.env.LODESTAR_CONFIG??s(o6,"config.toml"),K$=s(t,"daemon.pid"),u2=s(t,"daemon.log"),s6=s(t,"session-chat-map.json"),t6=s(t,"session-resume-map.json"),r6=s(t,"session-turns-map.json"),e6=s(t,"session-model-map.json"),$5=s(t,"temp-session-leases.json"),u3=s(t,"tasklist-map.json"),a1=s(t,"agent-runs"),BV=s(t,"agent-project-client.json"),d3=s(t,"agent-session-ids.json"),d2=l3.managedClaudePluginDir(),i2=s(t,"dsh"),jV=s(t,"codex-accounts"),_V=s(t,"codex-accounts.json"),PV=s(t,"codex-quota-blocks.json"),Z5=s(t,"agent-runtimes"),LV=s(t,"context-window-cache.json"),qV=s(t,"notify-callbacks.json"),J5=s(t,"alive-on-shutdown.json"),Q5=s(t,"inbox"),DV=s(t,"file-deliveries"),Y5=s(t,"file-delivery-groups.json"),o1=s(t,"debug.sock"),i3=s(t,"debug-context.json")});import{execFileSync as X5}from"node:child_process";import{readFileSync as FV,readlinkSync as e_,writeFileSync as $P}from"node:fs";import{isAbsolute as ZP,resolve as n3,win32 as V5}from"node:path";function JP(){if(!process.argv[1])throw Error("无法确定 daemon 入口路径");return n3(process.argv[1])}function QP($){if(!/^[1-9]\d*$/.test($.trim()))return null;let Z=Number($.trim());return Number.isSafeInteger(Z)&&Z<=2147483647?Z:null}function z5($){try{return process.kill($,0),!0}catch(Z){if(Z.code==="ESRCH")return!1;throw Z}}function YP($){if(!z5($))return null;try{let Z;if(process.platform==="linux")Z=FV(`/proc/${$}/cmdline`,"utf8");else if(process.platform==="darwin")Z=X5("ps",["-p",String($),"-o","args="],{encoding:"utf8",timeout:2000});else if(process.platform==="win32")Z=X5("powershell",["-NoProfile","-NonInteractive","-Command",`$ErrorActionPreference='Stop'; (Get-CimInstance Win32_Process -Filter 'ProcessId=${$}' -ErrorAction Stop).CommandLine`],{encoding:"utf8",timeout:5000});else throw Error(`不支持查询 ${process.platform} 平台的进程入口`);if(!Z.trim())throw Error(`PID ${$} 的命令行为空,无法核对 daemon 身份`);return Z.trim()}catch(Z){if(!z5($))return null;throw Error(`无法读取 PID ${$} 的命令行: ${Z instanceof Error?Z.message:String(Z)}`,{cause:Z})}}function GP($){let Z=$[0]?.replace(/\\/g,"/").split("/").pop()?.toLowerCase();if(!Z||!/^(?:node|nodejs|bun)(?:\.exe)?$/.test(Z))return null;let J=Z.startsWith("bun"),Q=J?zP:VP,Y=J?HP:XP,V=!1,X=1;while(X<$.length){let z=$[X];if(/^-[ep]/.test(z)||z==="--eval"||z==="--print"||/^(?:--eval|--print)=/.test(z))return null;if(!J&&(z==="-c"||z==="--check"||z==="--run"||z.startsWith("--run=")))return null;if(z==="--")return X+1;if(!z.startsWith("-")){if(J&&!V&&z==="run"){V=!0,X++;continue}return X}let H=z.split("=")[0];if(Q.has(H))X+=z.includes("=")?1:2;else if(Y.has(H))X++;else throw Error(`无法安全核对 daemon 入口: 未识别的 ${Z} 选项 ${z}`)}return null}function WP($){if(process.platform==="linux")return e_(`/proc/${$}/cwd`);if(process.platform==="darwin"){let J=X5("lsof",["-a","-p",String($),"-d","cwd","-Fn"],{encoding:"utf8",timeout:2000}).split(`
3
- `).find((Q)=>Q.startsWith("n"))?.slice(1);if(J)return J}throw Error(`无法确定 PID ${$} 的工作目录,不能核对相对 daemon 入口`)}function KP($,Z){if(!Number.isSafeInteger($)||$<=0||$>2147483647||!Z)return!1;let J=YP($);if(J===null)return!1;let Q=process.platform==="linux"?J.split("\x00").filter(Boolean):(J.match(/"[^"]*"|'[^']*'|\S+/g)??[]).map((X)=>X.replace(/^(?:"(.*)"|'(.*)')$/,"$1$2")),Y=GP(Q);if(Y===null||!Q[Y])return!1;let V=Q[Y];if(process.platform==="win32"){if(!V5.isAbsolute(V))throw Error(`PID ${$} 使用相对入口,无法安全核对 daemon 身份`);return V5.normalize(V).toLowerCase()===V5.normalize(Z).toLowerCase()}if(process.platform==="darwin"&&Z.startsWith(`${V} `))throw Error(`PID ${$} 的入口包含无法区分的空格,不能安全核对 daemon 身份`);if(!ZP(V))V=n3(WP($),V);return n3(V)===n3(Z)}function a3($){let Z;try{Z=FV($,"utf8")}catch(V){if(V.code==="ENOENT")return{state:"continue"};throw V}let J=Z.split(`
4
- `),Q=QP(J[0]??""),Y=(J[1]??"").trim();if(Q===null)throw Error(`PID 文件格式坏: ${$}`);if(!Y)return z5(Q)?{state:"exit",pid:Q}:{state:"continue"};return KP(Q,Y)?{state:"exit",pid:Q}:{state:"continue"}}function UV($){$P($,`${process.pid}
5
- ${JP()}`)}var VP,XP,zP,HP;var H5=N(()=>{VP=new Set(["-r","--require","--import","--loader","--experimental-loader","--conditions","-C","--inspect-port","--title","--icu-data-dir","--openssl-config","--redirect-warnings","--diagnostic-dir","--report-directory","--report-filename","--env-file","--env-file-if-exists","--watch-path","--unhandled-rejections","--max-old-space-size","--max-semi-space-size","--stack-size"]),XP=new Set(["--enable-source-maps","--no-warnings","--trace-warnings","--trace-uncaught","--preserve-symlinks","--preserve-symlinks-main","--inspect","--inspect-brk","--watch","--watch-preserve-output","--experimental-strip-types","--experimental-transform-types"]),zP=new Set(["--preload","--cwd","--config","-c","--env-file","--tsconfig-override"]),HP=new Set(["--hot","--watch","--smol","--no-clear-screen","--silent","--bun","--no-install"])});import{execFile as BP}from"node:child_process";import{readFile as jP}from"node:fs/promises";import{homedir as _P}from"node:os";import{join as MV}from"node:path";import{promisify as PP}from"node:util";import{Address4 as o3,Address6 as s3}from"ip-address";function n2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function $8($){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 G5($,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(o3.isValid(V))return o3.isValid(J)&&new o3(J).isInSubnet(new o3(V));if(s3.isValid(V))return s3.isValid(J)&&new s3(J).isInSubnet(new s3(V));throw Error("network proxy: invalid IP range in bypass list")}let X=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(X&&X[2]!==Q)return!1;let z=(X?X[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===z||J.endsWith(`.${z}`)})}function OV($,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 AV($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if($8($)||G5($,n2(Z,"NO_PROXY")))return;let Q=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Y=n2(Z,Q)||n2(Z,"ALL_PROXY");if(Y)return OV(Y,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(G5($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?OV(V,"system settings"):void 0}function e3($,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 qP($){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 DP($){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=e3(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=e3(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=e3(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 t3($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function FP($){let Z=new Map($.split(`
6
- `).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=t3(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=t3(Z.get(`.${Y}/host`));if(!V)continue;let X=new URL(e3(V,Z.get(`.${Y}/port`),Y==="socks"?"socks":"http"));if(Y==="http"&&Z.get(".http/use-authentication")==="true")X.username=t3(Z.get(".http/authentication-user")),X.password=t3(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 UP($){let Z=$.match(/^\[Proxy Settings\]\s*\n([\s\S]*?)(?=^\[|$(?![\s\S]))/m)?.[1];if(Z===void 0)return;let J=new Map(Z.split(`
7
- `).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 z=X.replace(/\s+(\d+)$/,":$1");Y[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(z)?z:`${V==="socks"?"socks":"http"}://${z}`}return Y}async function r3($,Z,J=5000){let{stdout:Q}=await LP($,Z,{encoding:"utf8",timeout:J,maxBuffer:262144,windowsHide:!0});return Q}async function OP(){if(process.platform==="win32")return qP(JSON.parse(await r3("powershell.exe",["-NoProfile","-NonInteractive","-Command",MP],15000)));if(process.platform==="darwin")return DP(await r3("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=MV(process.env.XDG_CONFIG_HOME||MV(_P(),".config"),"kioslaverc");try{let J=UP(await jP($,"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 r3("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return FP(await r3("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function AP($=OP,Z=process.env,J=Date.now){let Q;return async(Y)=>{if($8(Y)||G5(Y,n2(Z,"NO_PROXY"))||n2(Z,Y.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||n2(Z,"ALL_PROXY"))return AV(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 z=X instanceof Error?X.code??X.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${z})`,{cause:X})});Q={until:J()+30000,value:V}}return AV(Y,Z,await Q.value)}}var LP,MP,NV;var RV=N(()=>{LP=PP(BP);MP=String.raw`
2
+ import{createRequire as $L}from"node:module";var d_=Object.create;var{getPrototypeOf:i_,defineProperty:a6,getOwnPropertyNames:n_}=Object;var a_=Object.prototype.hasOwnProperty;function o_($){return this[$]}var s_,t_,HV=($,Z,J)=>{var Q=$!=null&&typeof $==="object";if(Q){var Y=Z?s_??=new WeakMap:t_??=new WeakMap,V=Y.get($);if(V)return V}J=$!=null?d_(i_($)):{};let X=Z||!$||!$.__esModule?a6(J,"default",{value:$,enumerable:!0}):J;for(let z of n_($))if(!a_.call(X,z))a6(X,z,{get:o_.bind($,z),enumerable:!0});if(Q)Y.set($,X);return X};var GV=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var r_=($)=>$;function e_($,Z){this[$]=r_.bind(null,Z)}var r$=($,Z)=>{for(var J in Z)a6($,J,{get:Z[J],enumerable:!0,configurable:!0,set:e_.bind(Z,J)})};var R=($,Z)=>()=>($&&(Z=$($=0)),Z);var l2=$L(import.meta.url);var o6=GV((sT,BV)=>{var{homedir:WV}=l2("node:os"),{join:z9}=l2("node:path");function KV(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return z9(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return z9(process.env.LOCALAPPDATA??z9(WV(),"AppData","Local"),"Lodestar");return z9(WV(),".local","share","lodestar")}function ZL(){return z9(KV(),"managed-claude-plugin")}BV.exports={lodestarDataDir:KV,managedClaudePluginDir:ZL}});import{homedir as JL}from"node:os";import{join as s}from"node:path";function YL($,Z,J){if($)return $;if(Z)return s(Z,"lodestar");return J}function VL(){if(QL)return s(process.env.APPDATA??s(jV,"AppData","Roaming"),"Lodestar");return s(jV,".config","lodestar")}var u3,jV,QL,s6,t,v0,K$,u2,t6,r6,e6,$5,Z5,d3,o1,_V,i3,d2,i2,LV,PV,qV,J5,DV,FV,Q5,Y5,UV,V5,s1,n3;var H0=R(()=>{u3=HV(o6(),1),jV=JL(),QL=process.platform==="win32";s6=YL(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,VL()),t=u3.lodestarDataDir(),v0=process.env.LODESTAR_CONFIG??s(s6,"config.toml"),K$=s(t,"daemon.pid"),u2=s(t,"daemon.log"),t6=s(t,"session-chat-map.json"),r6=s(t,"session-resume-map.json"),e6=s(t,"session-turns-map.json"),$5=s(t,"session-model-map.json"),Z5=s(t,"temp-session-leases.json"),d3=s(t,"tasklist-map.json"),o1=s(t,"agent-runs"),_V=s(t,"agent-project-client.json"),i3=s(t,"agent-session-ids.json"),d2=u3.managedClaudePluginDir(),i2=s(t,"dsh"),LV=s(t,"codex-accounts"),PV=s(t,"codex-accounts.json"),qV=s(t,"codex-quota-blocks.json"),J5=s(t,"agent-runtimes"),DV=s(t,"context-window-cache.json"),FV=s(t,"notify-callbacks.json"),Q5=s(t,"alive-on-shutdown.json"),Y5=s(t,"inbox"),UV=s(t,"file-deliveries"),V5=s(t,"file-delivery-groups.json"),s1=s(t,"debug.sock"),n3=s(t,"debug-context.json")});import{execFileSync as z5}from"node:child_process";import{readFileSync as MV,readlinkSync as XL,writeFileSync as zL}from"node:fs";import{isAbsolute as HL,resolve as a3,win32 as X5}from"node:path";function GL(){if(!process.argv[1])throw Error("无法确定 daemon 入口路径");return a3(process.argv[1])}function WL($){if(!/^[1-9]\d*$/.test($.trim()))return null;let Z=Number($.trim());return Number.isSafeInteger(Z)&&Z<=2147483647?Z:null}function H5($){try{return process.kill($,0),!0}catch(Z){if(Z.code==="ESRCH")return!1;throw Z}}function KL($){if(!H5($))return null;try{let Z;if(process.platform==="linux")Z=MV(`/proc/${$}/cmdline`,"utf8");else if(process.platform==="darwin")Z=z5("ps",["-p",String($),"-o","args="],{encoding:"utf8",timeout:2000});else if(process.platform==="win32")Z=z5("powershell",["-NoProfile","-NonInteractive","-Command",`$ErrorActionPreference='Stop'; (Get-CimInstance Win32_Process -Filter 'ProcessId=${$}' -ErrorAction Stop).CommandLine`],{encoding:"utf8",timeout:5000});else throw Error(`不支持查询 ${process.platform} 平台的进程入口`);if(!Z.trim())throw Error(`PID ${$} 的命令行为空,无法核对 daemon 身份`);return Z.trim()}catch(Z){if(!H5($))return null;throw Error(`无法读取 PID ${$} 的命令行: ${Z instanceof Error?Z.message:String(Z)}`,{cause:Z})}}function PL($){let Z=$[0]?.replace(/\\/g,"/").split("/").pop()?.toLowerCase();if(!Z||!/^(?:node|nodejs|bun)(?:\.exe)?$/.test(Z))return null;let J=Z.startsWith("bun"),Q=J?_L:BL,Y=J?LL:jL,V=!1,X=1;while(X<$.length){let z=$[X];if(/^-[ep]/.test(z)||z==="--eval"||z==="--print"||/^(?:--eval|--print)=/.test(z))return null;if(!J&&(z==="-c"||z==="--check"||z==="--run"||z.startsWith("--run=")))return null;if(z==="--")return X+1;if(!z.startsWith("-")){if(J&&!V&&z==="run"){V=!0,X++;continue}return X}let H=z.split("=")[0];if(Q.has(H))X+=z.includes("=")?1:2;else if(Y.has(H))X++;else throw Error(`无法安全核对 daemon 入口: 未识别的 ${Z} 选项 ${z}`)}return null}function qL($){if(process.platform==="linux")return XL(`/proc/${$}/cwd`);if(process.platform==="darwin"){let J=z5("lsof",["-a","-p",String($),"-d","cwd","-Fn"],{encoding:"utf8",timeout:2000}).split(`
3
+ `).find((Q)=>Q.startsWith("n"))?.slice(1);if(J)return J}throw Error(`无法确定 PID ${$} 的工作目录,不能核对相对 daemon 入口`)}function DL($,Z){if(!Number.isSafeInteger($)||$<=0||$>2147483647||!Z)return!1;let J=KL($);if(J===null)return!1;let Q=process.platform==="linux"?J.split("\x00").filter(Boolean):(J.match(/"[^"]*"|'[^']*'|\S+/g)??[]).map((X)=>X.replace(/^(?:"(.*)"|'(.*)')$/,"$1$2")),Y=PL(Q);if(Y===null||!Q[Y])return!1;let V=Q[Y];if(process.platform==="win32"){if(!X5.isAbsolute(V))throw Error(`PID ${$} 使用相对入口,无法安全核对 daemon 身份`);return X5.normalize(V).toLowerCase()===X5.normalize(Z).toLowerCase()}if(process.platform==="darwin"&&Z.startsWith(`${V} `))throw Error(`PID ${$} 的入口包含无法区分的空格,不能安全核对 daemon 身份`);if(!HL(V))V=a3(qL($),V);return a3(V)===a3(Z)}function o3($){let Z;try{Z=MV($,"utf8")}catch(V){if(V.code==="ENOENT")return{state:"continue"};throw V}let J=Z.split(`
4
+ `),Q=WL(J[0]??""),Y=(J[1]??"").trim();if(Q===null)throw Error(`PID 文件格式坏: ${$}`);if(!Y)return H5(Q)?{state:"exit",pid:Q}:{state:"continue"};return DL(Q,Y)?{state:"exit",pid:Q}:{state:"continue"}}function OV($){zL($,`${process.pid}
5
+ ${GL()}`)}var BL,jL,_L,LL;var G5=R(()=>{BL=new Set(["-r","--require","--import","--loader","--experimental-loader","--conditions","-C","--inspect-port","--title","--icu-data-dir","--openssl-config","--redirect-warnings","--diagnostic-dir","--report-directory","--report-filename","--env-file","--env-file-if-exists","--watch-path","--unhandled-rejections","--max-old-space-size","--max-semi-space-size","--stack-size"]),jL=new Set(["--enable-source-maps","--no-warnings","--trace-warnings","--trace-uncaught","--preserve-symlinks","--preserve-symlinks-main","--inspect","--inspect-brk","--watch","--watch-preserve-output","--experimental-strip-types","--experimental-transform-types"]),_L=new Set(["--preload","--cwd","--config","-c","--env-file","--tsconfig-override"]),LL=new Set(["--hot","--watch","--smol","--no-clear-screen","--silent","--bun","--no-install"])});import{execFile as FL}from"node:child_process";import{readFile as UL}from"node:fs/promises";import{homedir as ML}from"node:os";import{join as AV}from"node:path";import{promisify as OL}from"node:util";import{Address4 as s3,Address6 as t3}from"ip-address";function n2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function Z8($){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 W5($,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(s3.isValid(V))return s3.isValid(J)&&new s3(J).isInSubnet(new s3(V));if(t3.isValid(V))return t3.isValid(J)&&new t3(J).isInSubnet(new t3(V));throw Error("network proxy: invalid IP range in bypass list")}let X=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(X&&X[2]!==Q)return!1;let z=(X?X[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===z||J.endsWith(`.${z}`)})}function NV($,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 RV($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(Z8($)||W5($,n2(Z,"NO_PROXY")))return;let Q=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Y=n2(Z,Q)||n2(Z,"ALL_PROXY");if(Y)return NV(Y,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(W5($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?NV(V,"system settings"):void 0}function $8($,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 NL($){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 RL($){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=$8(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=$8(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=$8(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 r3($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function TL($){let Z=new Map($.split(`
6
+ `).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=r3(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=r3(Z.get(`.${Y}/host`));if(!V)continue;let X=new URL($8(V,Z.get(`.${Y}/port`),Y==="socks"?"socks":"http"));if(Y==="http"&&Z.get(".http/use-authentication")==="true")X.username=r3(Z.get(".http/authentication-user")),X.password=r3(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 EL($){let Z=$.match(/^\[Proxy Settings\]\s*\n([\s\S]*?)(?=^\[|$(?![\s\S]))/m)?.[1];if(Z===void 0)return;let J=new Map(Z.split(`
7
+ `).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 z=X.replace(/\s+(\d+)$/,":$1");Y[V==="socks"?"all":V]=/^[a-z][\w+.-]*:\/\//i.test(z)?z:`${V==="socks"?"socks":"http"}://${z}`}return Y}async function e3($,Z,J=5000){let{stdout:Q}=await AL($,Z,{encoding:"utf8",timeout:J,maxBuffer:262144,windowsHide:!0});return Q}async function SL(){if(process.platform==="win32")return NL(JSON.parse(await e3("powershell.exe",["-NoProfile","-NonInteractive","-Command",xL],15000)));if(process.platform==="darwin")return RL(await e3("/usr/sbin/scutil",["--proxy"]));if(process.platform==="linux"){let $=AV(process.env.XDG_CONFIG_HOME||AV(ML(),".config"),"kioslaverc");try{let J=EL(await UL($,"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 e3("gsettings",["list-schemas"])}catch(J){if(J?.code==="ENOENT")return{};throw J}if(!Z.split(/\r?\n/).includes("org.gnome.system.proxy"))return{};return TL(await e3("gsettings",["list-recursively","org.gnome.system.proxy"]))}return{}}function CL($=SL,Z=process.env,J=Date.now){let Q;return async(Y)=>{if(Z8(Y)||W5(Y,n2(Z,"NO_PROXY"))||n2(Z,Y.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY")||n2(Z,"ALL_PROXY"))return RV(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 z=X instanceof Error?X.code??X.name:"unknown error";throw Error(`network proxy: failed to read ${process.platform} system proxy settings (${z})`,{cause:X})});Q={until:J()+30000,value:V}}return RV(Y,Z,await Q.value)}}var AL,xL,TV;var EV=R(()=>{AL=OL(FL);xL=String.raw`
8
8
  $ErrorActionPreference = 'Stop'
9
9
  [Console]::OutputEncoding = New-Object Text.UTF8Encoding($false)
10
10
  Add-Type @'
@@ -42,64 +42,65 @@ try {
42
42
  if ($pointer -ne [IntPtr]::Zero) { [void][LodestarProxy]::GlobalFree($pointer) }
43
43
  }
44
44
  }
45
- `;NV=AP()});import{Agent as NP}from"node:http";import{Agent as RP}from"node:https";import{Readable as TV}from"node:stream";import TP from"node-fetch";import{HttpProxyAgent as EP}from"http-proxy-agent";import{HttpsProxyAgent as xP}from"https-proxy-agent";function bP($,Z){if(!Z)return $.protocol==="https:"?CP:SP;return $.protocol==="https:"?new xP(Z):new EP(Z)}async function kP($,Z,J){if(typeof Bun<"u"){let X=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[X.toLowerCase()]||process.env[X])){let z=await import("undici");return EV??=new z.Agent,await z.fetch($,{...Z,redirect:"manual",dispatcher:EV})}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 TP($,{method:Q.method,headers:Object.fromEntries(Q.headers),body:Q.body?TV.fromWeb(Q.body):void 0,signal:Q.signal,agent:bP($,J),redirect:"manual"}),V=Q.method==="HEAD"||[204,205,304].includes(Y.status)||!Y.body?null:TV.toWeb(Y.body);return new Response(V,{status:Y.status,statusText:Y.statusText,headers:[...Y.headers]})}async function xV($,Z,J,Q=NV){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&&!$8(Y))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let z=J?void 0:await Q(Y),H=await kP(Y,V,z),G=H.headers.get("location");if(![301,302,303,307,308].includes(H.status)||!G||Z.redirect==="manual")return H;if(await H.body?.cancel(),Z.redirect==="error")throw Error("network: redirect rejected");if(X>=20)throw Error("network: too many redirects");let W=new URL(G,Y),K=new Headers(V.headers);if(W.origin!==Y.origin)for(let _ of["authorization","proxy-authorization","cookie","host"])K.delete(_);let j=(V.method??"GET").toUpperCase();if(H.status===303&&j!=="HEAD"||[301,302].includes(H.status)&&j==="POST"){V={...V,method:"GET",body:void 0};for(let _ of["content-type","content-length","content-encoding"])K.delete(_)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=K,Y=W}}function V0($,Z={}){return xV($,Z,!1)}function SV($,Z={}){return xV($,Z,!0)}var SP,CP,EV;var p0=N(()=>{RV();SP=new NP({keepAlive:!0}),CP=new RP({keepAlive:!0})});function a2($){return $!==null&&typeof $==="object"?$:void 0}function N0($){return typeof $==="string"&&$.trim()?$:void 0}function Z8($){return typeof $==="number"&&Number.isFinite($)?$:N0($)}function w$($,Z){let J=a2($);if(!J)return;if(typeof J.get==="function"){let Y=N0(J.get.call($,Z));if(Y!==void 0)return Y}let Q=Object.keys(J).find((Y)=>Y.toLowerCase()===Z);return Q===void 0?void 0:N0(J[Q])}function W5($){return N0($?.logId)??N0($?.log_id)??N0(a2($?.error)?.log_id)}function A$($){let Z=a2($),J=a2(Z?.response),Q=a2(Z?.data),Y=Z8(Z?.code),V=Z8(Q?.code),X=typeof Y==="number"||typeof Y==="string"&&/^\d+$/.test(Y)||N0(Z?.apiMessage)!==void 0||N0(Z?.msg)!==void 0,z=V!==0&&V!=="0"&&(V!==void 0||N0(Q?.msg)!==void 0||W5(Q)!==void 0),H=a2(J?.data)??(!X&&z?Q:void 0),G=J?.headers,W=Z?.headers,K=J?.status??Z?.status??Z?.httpStatus;return{code:Z8(H?.code)??Z8(Z?.code),message:N0(H?.apiMessage)??N0(H?.msg)??N0(H?.message)??N0(Z?.apiMessage)??N0(Z?.msg)??N0(Z?.message)??N0($)??"MISS",logId:W5(H)??W5(Z)??w$(G,"x-tt-logid")??w$(W,"x-tt-logid")??w$(G,"x-request-id")??w$(W,"x-request-id")??w$(G,"request-id")??w$(W,"request-id"),status:typeof K==="number"?K:void 0,retryAfter:N0(Z?.retryAfter)??w$(G,"retry-after")??w$(W,"retry-after")??w$(G,"x-ogw-ratelimit-reset")??w$(W,"x-ogw-ratelimit-reset")}}function v($){let Z=A$($);return`code=${Z.code??"MISS"} message=${Z.message} log_id=${Z.logId??"MISS"}`}import{appendFileSync as kV,mkdirSync as wP,readdirSync as vP,unlinkSync as wV,existsSync as CV,statSync as yP,renameSync as fP,readFileSync as hP}from"node:fs";import{join as vV}from"node:path";function j5($="development"){return $!=="test"}function yV($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function fV($,Z=t){return vV(Z,`${K5}${yV($)}${B5}`)}function gP($){if(!$.startsWith(K5)||!$.endsWith(B5))return null;let Z=$.slice(K5.length,$.length-B5.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 hV($,Z=new Date,J=IP){let Q;try{Q=vP($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let X of Q){let z=gP(X);if(!z)continue;if(Math.round((Y.getTime()-z.getTime())/86400000)<J)continue;try{wV(vV($,X)),V++}catch{}}return V}function mP(){try{if(!CV(u2))return;let $=yP(u2);if(!$.isFile()||$.size===0)return;let Z=fV($.mtime);if(CV(Z)){kV(Z,hP(u2)),wV(u2);return}fP(u2,Z)}catch{}}function B($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
46
- `;if(process.stderr.write(J),!j5())return;try{let Q=yV(Z);if(bV!==Q)bV=Q,hV(t,Z);kV(fV(Z),J)}catch{}}var IP=7,K5="daemon-",B5=".log",bV=null;var h=N(()=>{H0();if(j5())try{wP(t,{recursive:!0})}catch{}if(j5()){mP();try{hV(t)}catch{}}});function J8($,Z={}){if(!$||typeof $!=="object")return!1;let{status:J,code:Q,message:Y}=A$($);if(Z.api==="cardkit"&&(Q===300308||Q==="300308")&&/^server internal error[.!]?$/i.test(Y.trim()))return!0;if(Q===99991400||Q===230020||Q===1061045||J!==void 0&&pP.has(J))return!0;if(typeof J==="number"&&J>=400)return!1;if(typeof Q==="string"&&cP.has(Q)||"name"in $&&$.name==="TimeoutError")return!0;return"cause"in $&&$.cause!==$&&J8($.cause,Z)}function lP($){let Z=A$($).retryAfter;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 s1($,Z,J={}){for(let Q=0;;Q++)try{return await Z()}catch(Y){let V=Math.max(_5[Q]??0,lP(Y)),X=J8(Y,J)&&Q<_5.length&&V<=60000;if(B(`feishu: ${$} attempt ${Q+1}/${_5.length+1} failed: ${v(Y)}; ${X?`retry in ${V}ms`:"FINAL"}`),!X){if(!(Y instanceof y0)&&Y&&typeof Y==="object"&&"response"in Y){let z=A$(Y),H=new y0(`${$}: ${v(Y)}`,z.status,z.code,z.retryAfter,z.logId,z.message);throw H.cause=Y,H}throw Y}await new Promise((z)=>setTimeout(z,V))}}async function B$($,Z){let J=await $.text(),Q=$.headers.get("retry-after")??$.headers.get("x-ogw-ratelimit-reset"),Y=A$({headers:$.headers}),V;try{V=JSON.parse(J)}catch{let X=`invalid JSON — ${J.slice(0,200)}`,z={message:X,logId:Y.logId};throw new y0(`${Z} HTTP ${$.status}: ${v(z)}`,$.status,void 0,Q,z.logId,X)}if(!$.ok||V?.code!==0){let X=A$({response:{data:V,headers:$.headers,status:$.status}});throw new y0(`${Z} HTTP ${$.status}: ${v(X)}`,$.status,X.code,Q,X.logId,X.message)}return V}var _5,pP,cP,y0;var o2=N(()=>{h();_5=[1000,4000],pP=new Set([408,429,500,502,503,504]),cP=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"]);y0=class y0 extends Error{status;code;retryAfter;logId;apiMessage;constructor($,Z,J,Q,Y,V=$){super($);this.status=Z;this.code=J;this.retryAfter=Q;this.logId=Y;this.apiMessage=V;this.name="FeishuRequestError"}}});function c0($,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 P5($){return $!==null&&typeof $==="object"&&!Array.isArray($)}function IV($){return typeof $==="string"||typeof $==="number"?String($):void 0}async function v$($,Z,J){try{if(!Z.trim())throw Error(`${J}: 请填写 API Key`);return await uP($,Z,J)}catch(Q){throw Error(c0(Q,[Z]))}}async function uP($,Z,J){let Q=await V0($,{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=P5(V)?V:void 0,z=P5(X?.error)?X.error:void 0,H=IV(z?.code??z?.type??X?.code),G=IV(z?.message??X?.msg??X?.message??X?.error),W=X?.success===!1||X?.error!=null||H!==void 0&&H!=="0"&&H!=="200";if(!Q.ok||W){let K=[H!==void 0?`code=${H}`:"",G].filter(Boolean).join(": "),j=`${J} HTTP ${Q.status}${K?`: ${K}`:""}`;throw Error(Z?j.replaceAll(Z,"[redacted]"):j)}if(!Array.isArray(X?.data))throw Error(`${J} 缺少 data 数组`);if(!X.data.length)throw Error(`${J} 模型目录为空`);if(!X.data.every(P5))throw Error(`${J} 模型目录包含无效条目`);return X.data}var s2=N(()=>{p0()});function z9($){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 r2($,Z){return(await v$(`${z9($)}/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 t2="https://open.bigmodel.cn/api/anthropic";var H9=N(()=>{s2()});import{chmodSync as dP,closeSync as L5,fsyncSync as gV,mkdirSync as iP,openSync as mV,renameSync as nP,unlinkSync as aP,writeFileSync as oP}from"node:fs";import{randomUUID as sP}from"node:crypto";import{dirname as pV}from"node:path";function $L($){let Z=pV($);iP(Z,{recursive:!0,mode:eP})}function cV($,Z,J){$L($);let Q=`${$}.${process.pid}.${sP()}.tmp`,Y=null;try{Y=mV(Q,"wx",J),oP(Y,Z),gV(Y),L5(Y),Y=null,nP(Q,$);try{dP($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=mV(pV($),"r"),gV(V)}catch{}finally{if(V!==null)try{L5(V)}catch{}}}}catch(V){if(Y!==null)try{L5(Y)}catch{}try{aP(Q)}catch{}throw V}}function r0($,Z){cV($,Z,tP)}function lV($,Z){cV($,Z,rP)}function a($,Z){r0($,JSON.stringify(Z,null,2)+`
47
- `)}var tP=384,rP=448,eP=448;var x0=()=>{};import{execFile as ZL}from"node:child_process";import{spawn as JL}from"cross-spawn";function YL($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{ZL("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Q,Y,V)=>{if(Q)J(Error(`taskkill npm installer PID ${$} failed: ${Q.message}
48
- ${Y}${V}`));else Z()})})}async function q5($,Z,J={}){Z?.throwIfAborted();let Q=J.platform??process.platform,Y=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,z)=>{let H=(J.spawn??JL)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${QL}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),G="",W,K,j=!1,_=!1,D,L=(O)=>{G=(G+O.toString()).slice(-16384)};H.stdout.on("data",L),H.stderr.on("data",L);let P=(O)=>{if(j)return;if(j=!0,clearTimeout(M),D)clearTimeout(D);if(Z?.removeEventListener("abort",A),O)z(O);else X()},F=(O)=>new Q8(`${W?.message??"Agent runtime install failed"}; npm installer PID ${H.pid??"MISS"} termination unconfirmed: ${O}; partial directory retained: ${$}
49
- ${G}`),U=(O)=>{if(j||_||K)return;W??=Error(O),D=setTimeout(()=>P(F(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(_)throw Error("installer closed before process-tree termination started");if(!H.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??YL)(H.pid);else if(!H.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((R)=>P(F(R instanceof Error?R.message:String(R))))},A=()=>U("Agent runtime install aborted"),M=setTimeout(()=>U(`Agent runtime install timed out after ${Y}ms`),Y);if(Z?.addEventListener("abort",A,{once:!0}),H.on("error",(O)=>{if(W??=O,!H.pid)P(Error(`${O.message}
50
- ${G}`))}),H.once("close",async(O,R)=>{_=!0,clearTimeout(M),Z?.removeEventListener("abort",A);try{await K}catch(w){P(F(w instanceof Error?w.message:String(w)));return}if(W||O!==0)P(Error(`${W?.message??`npm install exited code=${O} signal=${R}`}
51
- ${G}`));else P()}),Z?.aborted)A()})}var QL="https://registry.npmjs.org",Q8;var D5=N(()=>{Q8=class Q8 extends Error{}});import{createHash as VL,randomUUID as XL}from"node:crypto";import{createRequire as zL}from"node:module";import{existsSync as Y8,readFileSync as dV}from"node:fs";import{mkdir as iV,mkdtemp as HL,readFile as nV,rename as aV,rm as G9,writeFile as oV}from"node:fs/promises";import{join as e0,isAbsolute as GL}from"node:path";import{fileURLToPath as WL,pathToFileURL as KL}from"node:url";function sV($,Z=Z5){let J=e0(Z,$,"current.json");if(!Y8(J))return null;let Q=JSON.parse(dV(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!GL(Q.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Q}function V8($){let Z=sV($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!Y8(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function F5($,Z){return zL(e0(V8($),"package.json")).resolve(Z)}function W9($,Z){let J=e0(V8($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!Y8(J))throw Error(`${$} executable missing: ${J}`);return J}async function tV(){return import(KL(F5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function PL($,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 V0(`${_L}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Q.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let z=await X.json();if(z.name!==$||typeof z.version!=="string"||!z.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return z}finally{clearTimeout(V),J?.removeEventListener("abort",Y)}}async function LL($,Z){let J={};if($!=="dsh"){let X=await Promise.all(e2[$].map((z)=>Z(z,"latest")));for(let z of X)J[z.name]=z.version;return J}let Q=await Z("@deepseek-ai/dsh","latest"),Y=new Set(e2.dsh),V=new Set;while(Y.size){let X=[...Y].slice(0,12);for(let H of X)Y.delete(H),V.add(H);let z=await Promise.all(X.map((H)=>H===Q.name?Q:Z(H,Q.version)));for(let H of z){if(H.version!==Q.version)throw Error(`DSH release package mismatch: ${H.name}@${H.version}, expected ${Q.version}`);J[H.name]=H.version;for(let G of Object.keys({...H.dependencies,...H.peerDependencies,...H.optionalDependencies}))if(G.startsWith("@deepseek-ai/dsh")&&!V.has(G))Y.add(G)}}return J}async function U1($,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 qL($,Z){let J=e0($,`current-${XL()}.json`),Q;try{await oV(J,JSON.stringify(Z)+`
52
- `,{mode:384}),await U1(()=>aV(J,e0($,"current.json")))}catch(Y){throw Q=Y,Y}finally{try{await U1(()=>G9(J,{force:!0}))}catch(Y){if(Q)throw AggregateError([Q,Y],`${$4(Q)}; state temporary file cleanup failed: ${$4(Y)}`);throw Y}}}async function uV($,Z){for(let[J,Q]of Object.entries(Z)){let Y=JSON.parse(await nV(e0($,"node_modules",J,"package.json"),"utf8"));if(Y.name!==J||Y.version!==Q)throw Error(`Invalid Agent runtime at ${$}: expected ${J}@${Q}, found ${Y.name}@${Y.version}`)}}async function DL($,Z){let J=e0($,"update.lock"),Q=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await iV(J);try{await U1(async()=>r0(e0(J,"pid"),String(process.pid)))}catch(Y){try{await U1(()=>G9(J,{recursive:!0}))}catch(V){throw AggregateError([Y,V],`${$4(Y)}; runtime update lock cleanup failed: ${$4(V)}`)}throw Y}return()=>U1(()=>G9(J,{recursive:!0}))}catch(Y){if(Y.code!=="EEXIST")throw Y;try{let V=Number(await nV(e0(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 U1(()=>G9(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 X8($,Z={}){let J=Z.root??Z5,Q=e0(J,$);await iV(Q,{recursive:!0,mode:448});let Y=await DL(Q,Z.signal),V,X,z=!1;try{let H=sV($,J);Z.report?.(`${$}: 检查 upstream latest`);let G=await LL($,Z.metadata??((L,P)=>PL(L,P,Z.signal)));Z.signal?.throwIfAborted();let W=JSON.parse(dV(WL(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=VL("sha256").update(JSON.stringify({installFormat:$==="dsh"?3:2,versions:Object.entries(G).sort(),security:W,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),j=e0(Q,K);if(!Y8(j)){V=await HL(e0(Q,".install-")),await oV(e0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:G[e2[$][0]],private:!0,type:"module",dependencies:Object.fromEntries(e2[$].map((P)=>[P,G[P]])),overrides:{...W,...$==="dsh"?G:{}}})+`
53
- `,{mode:384}),await(Z.install??q5)(V,Z.signal),await uV(V,G),Z.signal?.throwIfAborted();let L=V;await U1(()=>aV(L,j)),V=void 0}else await uV(j,G);let _={directory:j,versions:G,checkedAt:Date.now()},D=H?.directory===j;return await qL(Q,_),Z.report?.(`${$}: ${e2[$][0]}@${G[e2[$][0]]}${D?" 已是 latest":" 已更新,新进程使用新版"}`),_}catch(H){throw X=H,z=H instanceof Q8,H}finally{let H=[];if(V&&!z){let G=V;try{await U1(()=>G9(G,{recursive:!0}))}catch(W){H.push(W)}}try{await Y()}catch(G){H.push(G)}if(H.length){let G=X?[X,...H]:H;throw AggregateError(G,G.map($4).join("; "))}}}function rV($,Z={}){let J=BL.filter((Q)=>Z.enabled?.[Q]===!0).map((Q)=>{let Y=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??X8)(Q,{report:$,signal:Y.signal}).catch((z)=>$(`${Q} 自动更新未完成: ${$4(z)}`)).finally(()=>{V=void 0})},jL);return X.unref(),()=>{clearInterval(X),Y.abort()}});return()=>{for(let Q of J)Q()}}var BL,jL=21600000,_L="https://registry.npmjs.org",e2,$4=($)=>$ instanceof Error?$.message:String($);var Z4=N(()=>{p0();H0();D5();x0();D5();BL=["codex","claude","dsh"],e2={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 $X;var eV=N(()=>{$X={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 XX={};r$(XX,{writeClaudeGlmEnv:()=>QX,testFeishuCreds:()=>YX,spawnDaemonDetached:()=>VX,runSetup:()=>kL});import{execFileSync as UL,spawn as H8}from"node:child_process";import{spawn as ML}from"cross-spawn";import{existsSync as M5,mkdirSync as JX,readFileSync as OL}from"node:fs";import{createInterface as AL}from"node:readline/promises";import{dirname as NL,join as O5}from"node:path";import{homedir as RL}from"node:os";import{fileURLToPath as TL}from"node:url";async function t1($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Q=(await K9.question(`${q.cyan}? ${q.reset}${$}${J}
54
- ${q.green}>${q.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Q}}function EL($){let Z="═".repeat(58);console.log(`
45
+ `;TV=CL()});import{Agent as bL}from"node:http";import{Agent as kL}from"node:https";import{Readable as xV}from"node:stream";import wL from"node-fetch";import{HttpProxyAgent as vL}from"http-proxy-agent";import{HttpsProxyAgent as yL}from"https-proxy-agent";function IL($,Z){if(!Z)return $.protocol==="https:"?hL:fL;return $.protocol==="https:"?new yL(Z):new vL(Z)}async function gL($,Z,J){if(typeof Bun<"u"){let X=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[X.toLowerCase()]||process.env[X])){let z=await import("undici");return SV??=new z.Agent,await z.fetch($,{...Z,redirect:"manual",dispatcher:SV})}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 wL($,{method:Q.method,headers:Object.fromEntries(Q.headers),body:Q.body?xV.fromWeb(Q.body):void 0,signal:Q.signal,agent:IL($,J),redirect:"manual"}),V=Q.method==="HEAD"||[204,205,304].includes(Y.status)||!Y.body?null:xV.toWeb(Y.body);return new Response(V,{status:Y.status,statusText:Y.statusText,headers:[...Y.headers]})}async function CV($,Z,J,Q=TV){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&&!Z8(Y))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let z=J?void 0:await Q(Y),H=await gL(Y,V,z),G=H.headers.get("location");if(![301,302,303,307,308].includes(H.status)||!G||Z.redirect==="manual")return H;if(await H.body?.cancel(),Z.redirect==="error")throw Error("network: redirect rejected");if(X>=20)throw Error("network: too many redirects");let W=new URL(G,Y),K=new Headers(V.headers);if(W.origin!==Y.origin)for(let _ of["authorization","proxy-authorization","cookie","host"])K.delete(_);let j=(V.method??"GET").toUpperCase();if(H.status===303&&j!=="HEAD"||[301,302].includes(H.status)&&j==="POST"){V={...V,method:"GET",body:void 0};for(let _ of["content-type","content-length","content-encoding"])K.delete(_)}else if(V.body instanceof ReadableStream)throw Error("network: cannot replay a streamed body after redirect");V.headers=K,Y=W}}function X0($,Z={}){return CV($,Z,!1)}function bV($,Z={}){return CV($,Z,!0)}var fL,hL,SV;var p0=R(()=>{EV();fL=new bL({keepAlive:!0}),hL=new kL({keepAlive:!0})});function a2($){return $!==null&&typeof $==="object"?$:void 0}function N0($){return typeof $==="string"&&$.trim()?$:void 0}function J8($){return typeof $==="number"&&Number.isFinite($)?$:N0($)}function w$($,Z){let J=a2($);if(!J)return;if(typeof J.get==="function"){let Y=N0(J.get.call($,Z));if(Y!==void 0)return Y}let Q=Object.keys(J).find((Y)=>Y.toLowerCase()===Z);return Q===void 0?void 0:N0(J[Q])}function K5($){return N0($?.logId)??N0($?.log_id)??N0(a2($?.error)?.log_id)}function A$($){let Z=a2($),J=a2(Z?.response),Q=a2(Z?.data),Y=J8(Z?.code),V=J8(Q?.code),X=typeof Y==="number"||typeof Y==="string"&&/^\d+$/.test(Y)||N0(Z?.apiMessage)!==void 0||N0(Z?.msg)!==void 0,z=V!==0&&V!=="0"&&(V!==void 0||N0(Q?.msg)!==void 0||K5(Q)!==void 0),H=a2(J?.data)??(!X&&z?Q:void 0),G=J?.headers,W=Z?.headers,K=J?.status??Z?.status??Z?.httpStatus;return{code:J8(H?.code)??J8(Z?.code),message:N0(H?.apiMessage)??N0(H?.msg)??N0(H?.message)??N0(Z?.apiMessage)??N0(Z?.msg)??N0(Z?.message)??N0($)??"MISS",logId:K5(H)??K5(Z)??w$(G,"x-tt-logid")??w$(W,"x-tt-logid")??w$(G,"x-request-id")??w$(W,"x-request-id")??w$(G,"request-id")??w$(W,"request-id"),status:typeof K==="number"?K:void 0,retryAfter:N0(Z?.retryAfter)??w$(G,"retry-after")??w$(W,"retry-after")??w$(G,"x-ogw-ratelimit-reset")??w$(W,"x-ogw-ratelimit-reset")}}function w($){let Z=A$($);return`code=${Z.code??"MISS"} message=${Z.message} log_id=${Z.logId??"MISS"}`}import{appendFileSync as vV,mkdirSync as mL,readdirSync as pL,unlinkSync as yV,existsSync as kV,statSync as cL,renameSync as lL,readFileSync as uL}from"node:fs";import{join as fV}from"node:path";function _5($="development"){return $!=="test"}function hV($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function IV($,Z=t){return fV(Z,`${B5}${hV($)}${j5}`)}function iL($){if(!$.startsWith(B5)||!$.endsWith(j5))return null;let Z=$.slice(B5.length,$.length-j5.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 gV($,Z=new Date,J=dL){let Q;try{Q=pL($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let X of Q){let z=iL(X);if(!z)continue;if(Math.round((Y.getTime()-z.getTime())/86400000)<J)continue;try{yV(fV($,X)),V++}catch{}}return V}function nL(){try{if(!kV(u2))return;let $=cL(u2);if(!$.isFile()||$.size===0)return;let Z=IV($.mtime);if(kV(Z)){vV(Z,uL(u2)),yV(u2);return}lL(u2,Z)}catch{}}function B($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
46
+ `;if(process.stderr.write(J),!_5())return;try{let Q=hV(Z);if(wV!==Q)wV=Q,gV(t,Z);vV(IV(Z),J)}catch{}}var dL=7,B5="daemon-",j5=".log",wV=null;var h=R(()=>{H0();if(_5())try{mL(t,{recursive:!0})}catch{}if(_5()){nL();try{gV(t)}catch{}}});function Q8($,Z={}){if(!$||typeof $!=="object")return!1;let{status:J,code:Q,message:Y}=A$($);if(Z.api==="cardkit"&&(Q===300308||Q==="300308")&&/^server internal error[.!]?$/i.test(Y.trim()))return!0;if(Q===99991400||Q===230020||Q===1061045||J!==void 0&&aL.has(J))return!0;if(typeof J==="number"&&J>=400)return!1;if(typeof Q==="string"&&oL.has(Q)||"name"in $&&$.name==="TimeoutError")return!0;return"cause"in $&&$.cause!==$&&Q8($.cause,Z)}function sL($){let Z=A$($).retryAfter;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 t1($,Z,J={}){for(let Q=0;;Q++)try{return await Z()}catch(Y){let V=Math.max(L5[Q]??0,sL(Y)),X=Q8(Y,J)&&Q<L5.length&&V<=60000;if(B(`feishu: ${$} attempt ${Q+1}/${L5.length+1} failed: ${w(Y)}; ${X?`retry in ${V}ms`:"FINAL"}`),!X){if(!(Y instanceof y0)&&Y&&typeof Y==="object"&&"response"in Y){let z=A$(Y),H=new y0(`${$}: ${w(Y)}`,z.status,z.code,z.retryAfter,z.logId,z.message);throw H.cause=Y,H}throw Y}await new Promise((z)=>setTimeout(z,V))}}async function B$($,Z){let J=await $.text(),Q=$.headers.get("retry-after")??$.headers.get("x-ogw-ratelimit-reset"),Y=A$({headers:$.headers}),V;try{V=JSON.parse(J)}catch{let X=`invalid JSON — ${J.slice(0,200)}`,z={message:X,logId:Y.logId};throw new y0(`${Z} HTTP ${$.status}: ${w(z)}`,$.status,void 0,Q,z.logId,X)}if(!$.ok||V?.code!==0){let X=A$({response:{data:V,headers:$.headers,status:$.status}});throw new y0(`${Z} HTTP ${$.status}: ${w(X)}`,$.status,X.code,Q,X.logId,X.message)}return V}var L5,aL,oL,y0;var o2=R(()=>{h();L5=[1000,4000],aL=new Set([408,429,500,502,503,504]),oL=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"]);y0=class y0 extends Error{status;code;retryAfter;logId;apiMessage;constructor($,Z,J,Q,Y,V=$){super($);this.status=Z;this.code=J;this.retryAfter=Q;this.logId=Y;this.apiMessage=V;this.name="FeishuRequestError"}}});function c0($,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 P5($){return $!==null&&typeof $==="object"&&!Array.isArray($)}function mV($){return typeof $==="string"||typeof $==="number"?String($):void 0}async function v$($,Z,J){try{if(!Z.trim())throw Error(`${J}: 请填写 API Key`);return await tL($,Z,J)}catch(Q){throw Error(c0(Q,[Z]))}}async function tL($,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=P5(V)?V:void 0,z=P5(X?.error)?X.error:void 0,H=mV(z?.code??z?.type??X?.code),G=mV(z?.message??X?.msg??X?.message??X?.error),W=X?.success===!1||X?.error!=null||H!==void 0&&H!=="0"&&H!=="200";if(!Q.ok||W){let K=[H!==void 0?`code=${H}`:"",G].filter(Boolean).join(": "),j=`${J} HTTP ${Q.status}${K?`: ${K}`:""}`;throw Error(Z?j.replaceAll(Z,"[redacted]"):j)}if(!Array.isArray(X?.data))throw Error(`${J} 缺少 data 数组`);if(!X.data.length)throw Error(`${J} 模型目录为空`);if(!X.data.every(P5))throw Error(`${J} 模型目录包含无效条目`);return X.data}var s2=R(()=>{p0()});function H9($){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 r2($,Z){return(await v$(`${H9($)}/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 t2="https://open.bigmodel.cn/api/anthropic";var G9=R(()=>{s2()});import{chmodSync as rL,closeSync as q5,fsyncSync as pV,mkdirSync as eL,openSync as cV,renameSync as $P,unlinkSync as ZP,writeFileSync as JP}from"node:fs";import{randomUUID as QP}from"node:crypto";import{dirname as lV}from"node:path";function zP($){let Z=lV($);eL(Z,{recursive:!0,mode:XP})}function uV($,Z,J){zP($);let Q=`${$}.${process.pid}.${QP()}.tmp`,Y=null;try{Y=cV(Q,"wx",J),JP(Y,Z),pV(Y),q5(Y),Y=null,$P(Q,$);try{rL($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=cV(lV($),"r"),pV(V)}catch{}finally{if(V!==null)try{q5(V)}catch{}}}}catch(V){if(Y!==null)try{q5(Y)}catch{}try{ZP(Q)}catch{}throw V}}function r0($,Z){uV($,Z,YP)}function dV($,Z){uV($,Z,VP)}function a($,Z){r0($,JSON.stringify(Z,null,2)+`
47
+ `)}var YP=384,VP=448,XP=448;var x0=()=>{};import{execFile as HP}from"node:child_process";import{spawn as GP}from"cross-spawn";function KP($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{HP("taskkill",["/PID",String($),"/T","/F"],{windowsHide:!0,timeout:1e4},(Q,Y,V)=>{if(Q)J(Error(`taskkill npm installer PID ${$} failed: ${Q.message}
48
+ ${Y}${V}`));else Z()})})}async function D5($,Z,J={}){Z?.throwIfAborted();let Q=J.platform??process.platform,Y=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,z)=>{let H=(J.spawn??GP)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${WP}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),G="",W,K,j=!1,_=!1,D,P=(O)=>{G=(G+O.toString()).slice(-16384)};H.stdout.on("data",P),H.stderr.on("data",P);let L=(O)=>{if(j)return;if(j=!0,clearTimeout(M),D)clearTimeout(D);if(Z?.removeEventListener("abort",A),O)z(O);else X()},F=(O)=>new Y8(`${W?.message??"Agent runtime install failed"}; npm installer PID ${H.pid??"MISS"} termination unconfirmed: ${O}; partial directory retained: ${$}
49
+ ${G}`),U=(O)=>{if(j||_||K)return;W??=Error(O),D=setTimeout(()=>L(F(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(_)throw Error("installer closed before process-tree termination started");if(!H.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??KP)(H.pid);else if(!H.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((T)=>L(F(T instanceof Error?T.message:String(T))))},A=()=>U("Agent runtime install aborted"),M=setTimeout(()=>U(`Agent runtime install timed out after ${Y}ms`),Y);if(Z?.addEventListener("abort",A,{once:!0}),H.on("error",(O)=>{if(W??=O,!H.pid)L(Error(`${O.message}
50
+ ${G}`))}),H.once("close",async(O,T)=>{_=!0,clearTimeout(M),Z?.removeEventListener("abort",A);try{await K}catch(k){L(F(k instanceof Error?k.message:String(k)));return}if(W||O!==0)L(Error(`${W?.message??`npm install exited code=${O} signal=${T}`}
51
+ ${G}`));else L()}),Z?.aborted)A()})}var WP="https://registry.npmjs.org",Y8;var F5=R(()=>{Y8=class Y8 extends Error{}});import{createHash as BP,randomUUID as jP}from"node:crypto";import{createRequire as _P}from"node:module";import{existsSync as V8,readFileSync as nV}from"node:fs";import{mkdir as aV,mkdtemp as LP,readFile as oV,rename as sV,rm as W9,writeFile as tV}from"node:fs/promises";import{join as e0,isAbsolute as PP}from"node:path";import{fileURLToPath as qP,pathToFileURL as DP}from"node:url";function rV($,Z=J5){let J=e0(Z,$,"current.json");if(!V8(J))return null;let Q=JSON.parse(nV(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!PP(Q.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Q}function X8($){let Z=rV($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!V8(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function U5($,Z){return _P(e0(X8($),"package.json")).resolve(Z)}function K9($,Z){let J=e0(X8($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!V8(J))throw Error(`${$} executable missing: ${J}`);return J}async function eV(){return import(DP(U5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function OP($,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(`${MP}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Q.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let z=await X.json();if(z.name!==$||typeof z.version!=="string"||!z.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return z}finally{clearTimeout(V),J?.removeEventListener("abort",Y)}}async function AP($,Z){let J={};if($!=="dsh"){let X=await Promise.all(e2[$].map((z)=>Z(z,"latest")));for(let z of X)J[z.name]=z.version;return J}let Q=await Z("@deepseek-ai/dsh","latest"),Y=new Set(e2.dsh),V=new Set;while(Y.size){let X=[...Y].slice(0,12);for(let H of X)Y.delete(H),V.add(H);let z=await Promise.all(X.map((H)=>H===Q.name?Q:Z(H,Q.version)));for(let H of z){if(H.version!==Q.version)throw Error(`DSH release package mismatch: ${H.name}@${H.version}, expected ${Q.version}`);J[H.name]=H.version;for(let G of Object.keys({...H.dependencies,...H.peerDependencies,...H.optionalDependencies}))if(G.startsWith("@deepseek-ai/dsh")&&!V.has(G))Y.add(G)}}return J}async function U1($,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 NP($,Z){let J=e0($,`current-${jP()}.json`),Q;try{await tV(J,JSON.stringify(Z)+`
52
+ `,{mode:384}),await U1(()=>sV(J,e0($,"current.json")))}catch(Y){throw Q=Y,Y}finally{try{await U1(()=>W9(J,{force:!0}))}catch(Y){if(Q)throw AggregateError([Q,Y],`${$4(Q)}; state temporary file cleanup failed: ${$4(Y)}`);throw Y}}}async function iV($,Z){for(let[J,Q]of Object.entries(Z)){let Y=JSON.parse(await oV(e0($,"node_modules",J,"package.json"),"utf8"));if(Y.name!==J||Y.version!==Q)throw Error(`Invalid Agent runtime at ${$}: expected ${J}@${Q}, found ${Y.name}@${Y.version}`)}}async function RP($,Z){let J=e0($,"update.lock"),Q=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await aV(J);try{await U1(async()=>r0(e0(J,"pid"),String(process.pid)))}catch(Y){try{await U1(()=>W9(J,{recursive:!0}))}catch(V){throw AggregateError([Y,V],`${$4(Y)}; runtime update lock cleanup failed: ${$4(V)}`)}throw Y}return()=>U1(()=>W9(J,{recursive:!0}))}catch(Y){if(Y.code!=="EEXIST")throw Y;try{let V=Number(await oV(e0(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 U1(()=>W9(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 z8($,Z={}){let J=Z.root??J5,Q=e0(J,$);await aV(Q,{recursive:!0,mode:448});let Y=await RP(Q,Z.signal),V,X,z=!1;try{let H=rV($,J);Z.report?.(`${$}: 检查 upstream latest`);let G=await AP($,Z.metadata??((P,L)=>OP(P,L,Z.signal)));Z.signal?.throwIfAborted();let W=JSON.parse(nV(qP(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=BP("sha256").update(JSON.stringify({installFormat:$==="dsh"?3:2,versions:Object.entries(G).sort(),security:W,platform:process.platform,arch:process.arch})).digest("hex").slice(0,20),j=e0(Q,K);if(!V8(j)){V=await LP(e0(Q,".install-")),await tV(e0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:G[e2[$][0]],private:!0,type:"module",dependencies:Object.fromEntries(e2[$].map((L)=>[L,G[L]])),overrides:{...W,...$==="dsh"?G:{}}})+`
53
+ `,{mode:384}),await(Z.install??D5)(V,Z.signal),await iV(V,G),Z.signal?.throwIfAborted();let P=V;await U1(()=>sV(P,j)),V=void 0}else await iV(j,G);let _={directory:j,versions:G,checkedAt:Date.now()},D=H?.directory===j;return await NP(Q,_),Z.report?.(`${$}: ${e2[$][0]}@${G[e2[$][0]]}${D?" 已是 latest":" 已更新,新进程使用新版"}`),_}catch(H){throw X=H,z=H instanceof Y8,H}finally{let H=[];if(V&&!z){let G=V;try{await U1(()=>W9(G,{recursive:!0}))}catch(W){H.push(W)}}try{await Y()}catch(G){H.push(G)}if(H.length){let G=X?[X,...H]:H;throw AggregateError(G,G.map($4).join("; "))}}}function $X($,Z={}){let J=FP.filter((Q)=>Z.enabled?.[Q]===!0).map((Q)=>{let Y=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??z8)(Q,{report:$,signal:Y.signal}).catch((z)=>$(`${Q} 自动更新未完成: ${$4(z)}`)).finally(()=>{V=void 0})},UP);return X.unref(),()=>{clearInterval(X),Y.abort()}});return()=>{for(let Q of J)Q()}}var FP,UP=21600000,MP="https://registry.npmjs.org",e2,$4=($)=>$ instanceof Error?$.message:String($);var Z4=R(()=>{p0();H0();F5();x0();F5();FP=["codex","claude","dsh"],e2={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 JX;var ZX=R(()=>{JX={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 HX={};r$(HX,{writeClaudeGlmEnv:()=>VX,testFeishuCreds:()=>XX,spawnDaemonDetached:()=>zX,runSetup:()=>gP});import{execFileSync as EP,spawn as G8}from"node:child_process";import{spawn as xP}from"cross-spawn";import{existsSync as O5,mkdirSync as YX,readFileSync as SP}from"node:fs";import{createInterface as CP}from"node:readline/promises";import{dirname as bP,join as A5}from"node:path";import{homedir as kP}from"node:os";import{fileURLToPath as wP}from"node:url";async function r1($,Z={}){while(!0){let J=Z.default?`${q.dim} [${Z.default}]${q.reset}`:"",Q=(await B9.question(`${q.cyan}? ${q.reset}${$}${J}
54
+ ${q.green}>${q.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${q.red}必填,请重新输入${q.reset}`);continue}return Q}}function vP($){let Z="═".repeat(58);console.log(`
55
55
  ${q.bold}${q.cyan}╔${Z}╗${q.reset}`),console.log(`${q.bold}${q.cyan}║ ${$.padEnd(54)} ║${q.reset}`),console.log(`${q.bold}${q.cyan}╚${Z}╝${q.reset}
56
- `)}function z8($,Z,J){console.log(`
56
+ `)}function H8($,Z,J){console.log(`
57
57
  ${q.bold}${q.yellow}[${$}/${Z}] ${J}${q.reset}
58
- `)}function U5($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function ZX($){try{let Z=UL($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function xL($){return new Promise((Z)=>{let J=ML($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Q)=>Z(Q===0)),J.on("error",()=>Z(!1))})}function SL(){return process.env.CLAUDE_CONFIG_DIR||O5(RL(),".claude")}async function CL($){let Z=await r2(t2,$),J=(H)=>{let G=H.match(/(\d+(?:\.\d+)?)/);return G?Number(G[1]):-1},Y=[...Z.filter((H)=>!/-Turbo|-Air/i.test(H))].sort((H,G)=>J(G)-J(H)),V=Y[0],X=Y[Y.length-1];if(!V)throw Error("GLM 模型目录中没有可用于 Claude Code slots 的模型");let z={ANTHROPIC_DEFAULT_OPUS_MODEL:`${V}[1m]`,ANTHROPIC_DEFAULT_SONNET_MODEL:`${V}[1m]`};if(X&&X!==V)z.ANTHROPIC_DEFAULT_HAIKU_MODEL=X;return z}async function QX($){try{let Z=SL();JX(Z,{recursive:!0});let J=O5(Z,"settings.json"),Q={};if(M5(J)){let z=OL(J,"utf8");try{let H=JSON.parse(z);if(!H||typeof H!=="object"||Array.isArray(H))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=H}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Y=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},V=await CL($),X={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:t2,API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"};return Object.assign(X,V),Q.env={...Y,...X},r0(J,JSON.stringify(Q,null,2)+`
59
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function bL($){let Z=(J)=>console.error(`无法打开浏览器,请手动打开 ${$}: ${J instanceof Error?J.message:String(J)}`);try{let J;if(process.platform==="win32")J=H8(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0});else if(process.platform==="darwin")J=H8("open",[$],{detached:!0,stdio:"ignore"});else J=H8("xdg-open",[$],{detached:!0,stdio:"ignore"});J.once("error",Z),J.unref()}catch(J){Z(J)}}async function YX($,Z){try{let J=await V0("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)}),Q=await B$(J,"飞书凭据校验");if(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书凭据校验缺少 tenant_access_token:${v(Q)}`}}catch(J){return{ok:!1,error:`飞书凭据校验失败:${v(J)}`}}}async function VX(){try{let $=NL(TL(import.meta.url)),Z=O5($,"lodestar.js");if(!M5(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=H8(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return await new Promise((Q)=>{J.once("error",(Y)=>Q({error:Y.message})),J.once("spawn",()=>{J.unref(),Q(J.pid?{pid:J.pid}:{error:"daemon 启动后未返回 PID"})})})}catch($){return{error:$?.message??String($)}}}async function kL(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(M5(v0)){if(console.log(`${q.yellow}发现已有配置: ${v0}${q.reset}`),(await t1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),K9.close();return}}EL("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(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await K9.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),z8(1,4,"准备 Claude Code CLI"),await X8("claude",{report:(W)=>console.log(W)}),console.log(`${q.green}✓ Claude Code / SDK 已更新${q.reset}: ${q.dim}${W9("claude","claude")}${q.reset}`),console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${q.reset}`),z8(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}此项可选,直接回车跳过;以后可在群内发送 glm-setup <api_key> 补配。${q.reset}`),console.log(` ${q.dim}使用本机 Claude Code 或 Codex 订阅不需要 GLM Key。此处填写智谱国内站 Key;Z.ai 请之后用 glm-setup 指定对应地址。${q.reset}`),console.log();while(!0){let W=await t1("GLM API key (直接回车跳过)",{});if(!W){console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);break}let K=await QX(W);if("path"in K){console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${K.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);break}else console.log(`${q.red}✗ GLM 配置失败:${q.reset} ${K.error}`),console.log(`${q.dim}请按错误提示处理后重新输入;直接回车可跳过,之后用群命令补配。${q.reset}`)}if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await t1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await X8("codex",{report:(K)=>console.log(K)});let W=W9("codex","codex");if(ZX(W))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await xL(W)&&ZX(W))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);z8(3,4,"Feishu 自建应用");let Z="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${Z}${q.reset}`),bL(Z),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}批量导入/导出权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${q.reset}`),console.log(JSON.stringify($X,null,2)),console.log(` ${q.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${q.reset}`),console.log(` ${q.dim}清单包含以下用途;也可按名称逐项开通:${q.reset}`),console.log(` ${q.dim}账号与认证信息 (排障):${q.reset}`),console.log(` • ${q.bold}verification:verification_information:readonly${q.reset} ${q.dim}# 查看账号主体认证状态${q.reset}`),console.log(` • ${q.bold}tenant:tenant:readonly${q.reset} ${q.dim}# 查看租户基本信息${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(` ${q.dim}云空间交付 (权限预先开通,功能仍按群开启):${q.reset}`),console.log(` • ${q.bold}drive:drive${q.reset} ${q.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${q.reset}`),console.log(` • ${q.bold}drive:file:upload${q.reset} ${q.dim}# 文件夹改名接口单独要求此权限${q.reset}`),console.log(` ${q.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${q.reset}`),console.log(` ${q.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let J="",Q="";while(!0){J=await t1("App ID (以 cli_ 开头)",{required:!0}),Q=await t1("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let W=await YX(J,Q);if(W.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${W.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await t1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),K9.close(),process.exit(1)}z8(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 t1("projects_root",{default:Y});JX(o6,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${U5(J)}"`,`app_secret = "${U5(Q)}"`,"","[runtime]",`projects_root = "${U5(V)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];r0(v0,X.join(`
58
+ `)}function M5($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function QX($){try{let Z=EP($,["login","status"],{timeout:1e4,shell:process.platform==="win32"}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function yP($){return new Promise((Z)=>{let J=xP($,["login"],{stdio:"inherit",shell:!1});J.on("exit",(Q)=>Z(Q===0)),J.on("error",()=>Z(!1))})}function fP(){return process.env.CLAUDE_CONFIG_DIR||A5(kP(),".claude")}async function hP($){let Z=await r2(t2,$),J=(H)=>{let G=H.match(/(\d+(?:\.\d+)?)/);return G?Number(G[1]):-1},Y=[...Z.filter((H)=>!/-Turbo|-Air/i.test(H))].sort((H,G)=>J(G)-J(H)),V=Y[0],X=Y[Y.length-1];if(!V)throw Error("GLM 模型目录中没有可用于 Claude Code slots 的模型");let z={ANTHROPIC_DEFAULT_OPUS_MODEL:`${V}[1m]`,ANTHROPIC_DEFAULT_SONNET_MODEL:`${V}[1m]`};if(X&&X!==V)z.ANTHROPIC_DEFAULT_HAIKU_MODEL=X;return z}async function VX($){try{let Z=fP();YX(Z,{recursive:!0});let J=A5(Z,"settings.json"),Q={};if(O5(J)){let z=SP(J,"utf8");try{let H=JSON.parse(z);if(!H||typeof H!=="object"||Array.isArray(H))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Q=H}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Y=Q.env&&typeof Q.env==="object"&&!Array.isArray(Q.env)?Q.env:{},V=await hP($),X={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:t2,API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"};return Object.assign(X,V),Q.env={...Y,...X},r0(J,JSON.stringify(Q,null,2)+`
59
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function IP($){let Z=(J)=>console.error(`无法打开浏览器,请手动打开 ${$}: ${J instanceof Error?J.message:String(J)}`);try{let J;if(process.platform==="win32")J=G8(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0});else if(process.platform==="darwin")J=G8("open",[$],{detached:!0,stdio:"ignore"});else J=G8("xdg-open",[$],{detached:!0,stdio:"ignore"});J.once("error",Z),J.unref()}catch(J){Z(J)}}async function XX($,Z){try{let J=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)}),Q=await B$(J,"飞书凭据校验");if(Q.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书凭据校验缺少 tenant_access_token:${w(Q)}`}}catch(J){return{ok:!1,error:`飞书凭据校验失败:${w(J)}`}}}async function zX(){try{let $=bP(wP(import.meta.url)),Z=A5($,"lodestar.js");if(!O5(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=G8(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return await new Promise((Q)=>{J.once("error",(Y)=>Q({error:Y.message})),J.once("spawn",()=>{J.unref(),Q(J.pid?{pid:J.pid}:{error:"daemon 启动后未返回 PID"})})})}catch($){return{error:$?.message??String($)}}}async function gP(){if(!process.stdin.isTTY)console.error(`${q.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${q.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(O5(v0)){if(console.log(`${q.yellow}发现已有配置: ${v0}${q.reset}`),(await r1("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),B9.close();return}}vP("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(` ${q.dim}1) 确保 Claude Code CLI 已装好${q.reset}`),console.log(` ${q.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${q.reset}`),console.log(` ${q.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${q.reset}`),console.log(` ${q.dim}4) 工作目录, 自动启动 daemon${q.reset}`),console.log(),await B9.question(`${q.dim}按 Enter 开始 (Ctrl+C 退出)...${q.reset}`),H8(1,4,"准备 Claude Code CLI"),await z8("claude",{report:(W)=>console.log(W)}),console.log(`${q.green}✓ Claude Code / SDK 已更新${q.reset}: ${q.dim}${K9("claude","claude")}${q.reset}`),console.log(),console.log(`${q.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${q.reset}`),console.log(`${q.dim}使用 Claude 订阅时,在本机运行 \`claude auth login\`;完成后在 model 面板选择 Claude Code 订阅。${q.reset}`),H8(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${q.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${q.reset}`),console.log(` ${q.dim}此项可选,直接回车跳过;以后可在群内发送 glm-setup <api_key> 补配。${q.reset}`),console.log(` ${q.dim}使用本机 Claude Code 或 Codex 订阅不需要 GLM Key。此处填写智谱国内站 Key;Z.ai 请之后用 glm-setup 指定对应地址。${q.reset}`),console.log();while(!0){let W=await r1("GLM API key (直接回车跳过)",{});if(!W){console.log(`${q.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${q.reset}`);break}let K=await VX(W);if("path"in K){console.log(`${q.green}✓ GLM 路由已写入${q.reset}: ${q.dim}${K.path}${q.reset}`),console.log(`${q.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${q.reset}`);break}else console.log(`${q.red}✗ GLM 配置失败:${q.reset} ${K.error}`),console.log(`${q.dim}请按错误提示处理后重新输入;直接回车可跳过,之后用群命令补配。${q.reset}`)}if(console.log(),console.log(`${q.bold}Codex (可选第二后端)${q.reset}`),console.log(` ${q.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${q.reset}`),(await r1("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){await z8("codex",{report:(K)=>console.log(K)});let W=K9("codex","codex");if(QX(W))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else if(console.log(`${q.dim}启动 \`codex login\`...${q.reset}`),await yP(W)&&QX(W))console.log(`${q.green}✓ Codex 已登录 ChatGPT${q.reset}`);else console.log(`${q.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${q.reset}`)}else console.log(`${q.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${q.reset}`);H8(3,4,"Feishu 自建应用");let Z="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${q.cyan}${Z}${q.reset}`),IP(Z),console.log(`${q.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${q.reset}`),console.log(),console.log(`${q.bold}详细操作步骤:${q.reset}`),console.log(),console.log(` ${q.bold}① 创建应用${q.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${q.dim}Lodestar${q.reset}), logo 随意。`),console.log(),console.log(` ${q.bold}② 添加机器人能力${q.reset}`),console.log(` 左侧菜单 "${q.cyan}添加应用能力${q.reset}" → 找到 "机器人" → 点 "${q.bold}添加${q.reset}" 按钮。`),console.log(),console.log(` ${q.bold}③ 申请权限 (左侧 "${q.cyan}权限管理${q.reset}" → "${q.bold}批量导入/导出权限${q.reset}")${q.reset}`),console.log(` ${q.yellow}选择应用身份权限,复制下方完整 JSON 批量导入,一次开齐账号信息、消息、卡片和云空间能力。${q.reset}`),console.log(JSON.stringify(JX,null,2)),console.log(` ${q.dim}无需用户身份权限或飞书 CLI 登录。权限申请后须完成审批,并在步骤 ⑤ 发布飞书应用版本。${q.reset}`),console.log(` ${q.dim}清单包含以下用途;也可按名称逐项开通:${q.reset}`),console.log(` ${q.dim}账号与认证信息 (排障):${q.reset}`),console.log(` • ${q.bold}verification:verification_information:readonly${q.reset} ${q.dim}# 查看账号主体认证状态${q.reset}`),console.log(` • ${q.bold}tenant:tenant:readonly${q.reset} ${q.dim}# 查看租户基本信息${q.reset}`),console.log(` ${q.dim}消息类:${q.reset}`),console.log(` • ${q.bold}im:message:send_as_bot${q.reset} ${q.dim}# 以机器人身份发消息${q.reset}`),console.log(` • ${q.bold}im:message${q.reset} ${q.dim}# 接收/操作消息 (核心)${q.reset}`),console.log(` • ${q.bold}im:chat${q.reset} ${q.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${q.reset}`),console.log(` • ${q.bold}im:chat:create${q.reset} ${q.dim}# wt: 自动创建 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat:delete${q.reset} ${q.dim}# wt: 解散 worktree 群${q.reset}`),console.log(` • ${q.bold}im:chat.members:read${q.reset} ${q.dim}# wt: 判断发起人是否已在群内${q.reset}`),console.log(` • ${q.bold}im:chat.members:write_only${q.reset} ${q.dim}# wt: 把发起人拉进已有 worktree 群${q.reset}`),console.log(` • ${q.bold}im:resource${q.reset} ${q.dim}# 上传/下载附件 (图文双向)${q.reset}`),console.log(` • ${q.bold}im:message.urgent${q.reset} ${q.dim}# 加急推送 (锁屏通知 / Ask)${q.reset}`),console.log(` • ${q.bold}im:message.group_msg${q.reset} ${q.dim}# 敏感: 接收群里所有消息${q.reset}`),console.log(` ${q.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${q.reset}`),console.log(` ${q.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${q.reset}`),console.log(` • ${q.bold}im:message.group_at_msg:readonly${q.reset} ${q.dim}# 读 @ 机器人消息 (兜底)${q.reset}`),console.log(` ${q.dim}卡片类 (Card Kit):${q.reset}`),console.log(` • ${q.bold}cardkit:card:read${q.reset} ${q.dim}# 读卡片状态${q.reset}`),console.log(` • ${q.bold}cardkit:card:write${q.reset} ${q.dim}# 创建/更新卡片 (流式渲染核心)${q.reset}`),console.log(` ${q.dim}云空间交付 (权限预先开通,功能仍按群开启):${q.reset}`),console.log(` • ${q.bold}drive:drive${q.reset} ${q.dim}# 上传、创建目录、协作者授权、关闭并核对文件链接分享${q.reset}`),console.log(` • ${q.bold}drive:file:upload${q.reset} ${q.dim}# 文件夹改名接口单独要求此权限${q.reset}`),console.log(` ${q.dim}默认仍直接发聊天附件;在指定群发送 files on 开启云空间,files off 恢复附件。${q.reset}`),console.log(` ${q.yellow}只取得 tenant_access_token 不代表以上权限已生效;缺少权限时群内命令会明确报错。${q.reset}`),console.log(),console.log(` ${q.bold}④ 订阅事件 (左侧 "${q.cyan}事件与回调${q.reset}", 拆两个子页:)${q.reset}`),console.log(` ${q.dim}a)${q.reset} ${q.bold}事件配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}im.message.receive_v1${q.reset} ${q.dim}# 收群消息${q.reset}`),console.log(` ${q.dim}b)${q.reset} ${q.bold}回调配置${q.reset} 页:`),console.log(` ${q.yellow}• "订阅方式" → 选 "长连接" → 点保存${q.reset}`),console.log(` • 添加事件: ${q.bold}card.action.trigger${q.reset} ${q.dim}# 卡片按钮点击回调${q.reset}`),console.log(),console.log(` ${q.bold}⑤ 发布版本${q.reset}`),console.log(` 页面顶部 "${q.bold}创建版本${q.reset}" → 滚到底点 "${q.bold}保存${q.reset}" → 弹框点 "${q.bold}发布${q.reset}"。`),console.log(` ${q.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${q.reset}`),console.log(),console.log(` ${q.bold}⑥ 拿凭据${q.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${q.bold}App ID${q.reset} (${q.dim}cli_...${q.reset}) 和 ${q.bold}App Secret${q.reset}, 待会粘到下面。`),console.log(),console.log(` ${q.bold}⑦ 把机器人拉进群${q.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${q.yellow}群名要等于 projects_root 下的项目目录名${q.reset} (下一步设, 默认是用户主目录)。`),console.log();let J="",Q="";while(!0){J=await r1("App ID (以 cli_ 开头)",{required:!0}),Q=await r1("App Secret",{required:!0}),console.log(`${q.dim}测试中... (调 tenant_access_token endpoint)${q.reset}`);let W=await XX(J,Q);if(W.ok){console.log(`${q.green}✓ Feishu 凭据测试通过${q.reset}`);break}if(console.log(`${q.red}✗ 测试失败:${q.reset} ${W.error}`),console.log(`${q.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${q.reset}`),console.log(),(await r1("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${q.yellow}已取消, 配置未写盘。${q.reset}`),B9.close(),process.exit(1)}H8(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 r1("projects_root",{default:Y});YX(s6,{recursive:!0});let X=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${M5(J)}"`,`app_secret = "${M5(Q)}"`,"","[runtime]",`projects_root = "${M5(V)}"`,"","[runtime.agent_auto_update]","codex = false","claude = false","dsh = false",""];r0(v0,X.join(`
60
60
  `)),console.log(`
61
61
  ${q.green}${q.bold}✓ 配置已写入${q.reset}`),console.log(` ${q.cyan}${v0}${q.reset}`),console.log(`
62
- ${q.bold}启动 daemon...${q.reset}`);let z=await VX(),H=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("pid"in z)console.log(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${z.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${V}${H}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${G}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${z.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),K9.close()}var q,K9;var zX=N(()=>{p0();o2();H9();H0();x0();Z4();eV();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},K9=AL({input:process.stdin,output:process.stdout})});class W8{label;interval;load;pending;timer;dueAt;failures=0;retired=!1;constructor($,Z,J,Q=0){this.label=$;this.interval=Z;this.load=J;this.dueAt=Q,G8.add(this),this.schedule()}get nextRefreshAt(){return this.dueAt}refresh(){if(this.retired)return Promise.resolve();if(this.pending)return this.pending;clearTimeout(this.timer);let $=Promise.resolve().then(()=>this.retired?void 0:this.load()).then(()=>{this.failures=0,this.dueAt=Date.now()+this.interval},(Z)=>{this.failures++;let J=Number(Z?.retryAfterMs);throw this.dueAt=Date.now()+Math.max(Math.min(300000,60000*2**Math.min(this.failures-1,3)),Number.isFinite(J)?J:0),B(`${this.label} refresh MISS: ${Z instanceof Error?Z.message:String(Z)}`),Z}).finally(()=>{if(this.pending===$)this.pending=void 0;this.schedule()});return this.pending=$,$}schedule(){if(clearTimeout(this.timer),!A5||this.retired||this.pending)return;this.timer=setTimeout(()=>{this.refresh().catch(()=>{})},Math.max(0,this.dueAt-Date.now())),this.timer.unref?.()}dispose(){this.retired=!0,clearTimeout(this.timer),G8.delete(this)}}function HX(){A5=!0;for(let $ of G8)$.schedule()}function GX(){A5=!1;for(let $ of G8)$.schedule()}var G8,A5=!1;var N5=N(()=>{h();G8=new Set});import{createHash as wL,randomUUID as R5}from"node:crypto";import{existsSync as K8,lstatSync as B8,mkdirSync as T5,readFileSync as WX,readdirSync as vL,realpathSync as J4,rmSync as yL,symlinkSync as fL,writeFileSync as hL}from"node:fs";import{homedir as IL}from"node:os";import{isAbsolute as gL,join as e$,relative as mL,resolve as pL,sep as cL}from"node:path";class KX{defaultHome;root;stateFile;defaultLoginRevision;constructor($=pL(process.env.CODEX_HOME||e$(IL(),".codex")),Z=jV,J=_V){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!K8(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(WX(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!==c&&!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:c,name:"默认",...this.defaultLoginRevision?{revision:this.defaultLoginRevision}:{}},...this.read().accounts.map(($)=>({...$}))]}get($){let Z=this.list().find((J)=>J.id===$);if(!Z)throw Error(`Codex 账号不存在:${$}`);return Z}find($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(c);let Z=this.list().find((J)=>this.nameKey(J.name)===this.nameKey($));if(!Z)throw Error(`Codex 账号不存在:${$};先发送 codex-login ${$}`);return Z}ensure($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(c);this.validateName($);let Z=this.read(),J=Z.accounts.find((Y)=>this.nameKey(Y.name)===this.nameKey($));if(J)return{...J};let Q={id:R5(),name:$.normalize("NFC").trim()};return Z.accounts.push(Q),a(this.stateFile,Z),Q}remove($){let Z=this.get($);if($===c)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(M1($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(_8($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Q=this.home($),Y;try{Y=B8(Q)}catch(X){if(X.code!=="ENOENT")throw X}if(Y){if(Y.isSymbolicLink()||!Y.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(K8(this.defaultHome)){let X=mL(J4(Q),J4(this.defaultHome));if(!X||!gL(X)&&X!==".."&&!X.startsWith(`..${cL}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{yL(Q,{recursive:!0})}catch(X){throw Error(`账号文件删除失败,账号记录已保留;${X}`)}}J.accounts=J.accounts.filter((X)=>X.id!==$);let V=0;for(let[X,z]of Object.entries(J.selections)){if(z!==$)continue;delete J.selections[X],V++}try{a(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[$]:c}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],a(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),a(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($===c){this.defaultLoginRevision=R5();return}let Q=J.accounts.find((Y)=>Y.id===$);if(!Q)throw Error("登录完成时账号记录已不存在");Object.assign(Q,{email:Z.email,planType:Z.planType,revision:R5()}),a(this.stateFile,J)}home($=c){return $===c?this.defaultHome:e$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===c)return Z;let J;try{J=B8(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(T5(Z,{recursive:!0,mode:448}),T5(this.defaultHome,{recursive:!0,mode:448}),J4(Z)===J4(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Q;try{Q=B8(e$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Q?.isSymbolicLink()||Q&&!Q.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{hL(e$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of lL){let X=e$(this.defaultHome,V);T5(X,{recursive:!0,mode:448}),this.link(X,e$(Z,V),!0)}let Y=new Set([...uL,...vL(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Y){let X=e$(this.defaultHome,V);if(K8(X))this.link(X,e$(Z,V),!1)}return Z}link($,Z,J){let Q;try{Q=B8(Z)}catch(Y){if(Y.code!=="ENOENT")throw Y}if(Q){if(!Q.isSymbolicLink()||J4(Z)!==J4($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}fL($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Q=!1){if(!Q&&M1($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Y=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Y};if($!==c){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($),$===c?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=e$(this.home($),"auth.json");if(!K8(Z))return null;let Q=JSON.parse(WX(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 wL("sha256").update(JSON.stringify([Q.account_id,V.sub])).digest("hex")}}function O1($,Z,J=!0){if(BX.set($,Z),!j8.has($))$.once("exit",()=>j8.delete($));j8.set($,{id:Z,ownsNativeProcess:J})}function _8($,Z=!1){return[...j8].some(([J,Q])=>Q.id===$&&(Q.ownsNativeProcess||Z)&&J.isAlive())}function M1($){return B9.has($)}function jX($){if(B9.has($))throw Error("该账号已有登录任务");if(_8($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return B9.set($,Z),()=>{if(B9.get($)===Z)B9.delete($)}}function j$($){return $?BX.get($)??c:c}var c="default",lL,uL,y,BX,j8,B9;var j0=N(()=>{H0();x0();lL=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],uL=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];y=new KX,BX=new WeakMap,j8=new Map;B9=new Map});import{readFileSync as dL}from"node:fs";import{homedir as PX}from"node:os";function _X($){return $.replace(/^~(?=\/|$)/,PX())}function iL($){let Z={_:{}},J="_";for(let Q of $.split(`
63
- `)){let Y=nL(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 z=X[2].trim(),H=z.startsWith('"')&&z.endsWith('"'),G=z.startsWith("'")&&z.endsWith("'");if(H||G){if(z=z.slice(1,-1),H)z=z.replace(/\\([\\"])/g,"$1")}Z[J][X[1]]=z}}return Z}function nL($){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 j9(){let $;try{$=dL(v0,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${v0}
62
+ ${q.bold}启动 daemon...${q.reset}`);let z=await zX(),H=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("pid"in z)console.log(`${q.green}✓ daemon 已在后台启动${q.reset} (pid ${z.pid})`),console.log(),console.log(`${q.bold}最后一步: 在 Feishu 验证${q.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${q.cyan}${V}${H}<群名>${q.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${q.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${q.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${q.cyan}${G}${q.reset}`),console.log(),console.log(`${q.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${q.reset}`);else console.log(`${q.yellow}启动失败: ${z.error}${q.reset}`),console.log(`手动运行: ${q.cyan}lodestar-daemon${q.reset}`);console.log(),B9.close()}var q,B9;var GX=R(()=>{p0();o2();G9();H0();x0();Z4();ZX();q={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},B9=CP({input:process.stdin,output:process.stdout})});class K8{label;interval;load;pending;timer;dueAt;failures=0;retired=!1;constructor($,Z,J,Q=0){this.label=$;this.interval=Z;this.load=J;this.dueAt=Q,W8.add(this),this.schedule()}get nextRefreshAt(){return this.dueAt}refresh(){if(this.retired)return Promise.resolve();if(this.pending)return this.pending;clearTimeout(this.timer);let $=Promise.resolve().then(()=>this.retired?void 0:this.load()).then(()=>{this.failures=0,this.dueAt=Date.now()+this.interval},(Z)=>{this.failures++;let J=Number(Z?.retryAfterMs);throw this.dueAt=Date.now()+Math.max(Math.min(300000,60000*2**Math.min(this.failures-1,3)),Number.isFinite(J)?J:0),B(`${this.label} refresh MISS: ${Z instanceof Error?Z.message:String(Z)}`),Z}).finally(()=>{if(this.pending===$)this.pending=void 0;this.schedule()});return this.pending=$,$}schedule(){if(clearTimeout(this.timer),!N5||this.retired||this.pending)return;this.timer=setTimeout(()=>{this.refresh().catch(()=>{})},Math.max(0,this.dueAt-Date.now())),this.timer.unref?.()}dispose(){this.retired=!0,clearTimeout(this.timer),W8.delete(this)}}function WX(){N5=!0;for(let $ of W8)$.schedule()}function KX(){N5=!1;for(let $ of W8)$.schedule()}var W8,N5=!1;var R5=R(()=>{h();W8=new Set});import{createHash as mP,randomUUID as T5}from"node:crypto";import{existsSync as B8,lstatSync as j8,mkdirSync as E5,readFileSync as BX,readdirSync as pP,realpathSync as J4,rmSync as cP,symlinkSync as lP,writeFileSync as uP}from"node:fs";import{homedir as dP}from"node:os";import{isAbsolute as iP,join as e$,relative as nP,resolve as aP,sep as oP}from"node:path";class jX{defaultHome;root;stateFile;defaultLoginRevision;constructor($=aP(process.env.CODEX_HOME||e$(dP(),".codex")),Z=LV,J=PV){this.defaultHome=$;this.root=Z;this.stateFile=J}read(){if(!B8(this.stateFile))return{version:1,accounts:[],selections:{}};let $=JSON.parse(BX(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!==l&&!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:l,name:"默认",...this.defaultLoginRevision?{revision:this.defaultLoginRevision}:{}},...this.read().accounts.map(($)=>({...$}))]}get($){let Z=this.list().find((J)=>J.id===$);if(!Z)throw Error(`Codex 账号不存在:${$}`);return Z}find($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(l);let Z=this.list().find((J)=>this.nameKey(J.name)===this.nameKey($));if(!Z)throw Error(`Codex 账号不存在:${$};先发送 codex-login ${$}`);return Z}ensure($=""){if(!$.trim()||["default","默认"].includes(this.nameKey($)))return this.get(l);this.validateName($);let Z=this.read(),J=Z.accounts.find((Y)=>this.nameKey(Y.name)===this.nameKey($));if(J)return{...J};let Q={id:T5(),name:$.normalize("NFC").trim()};return Z.accounts.push(Q),a(this.stateFile,Z),Q}remove($){let Z=this.get($);if($===l)throw Error("默认账号由设备原生 Codex 管理,不能用此命令删除");if(M1($))throw Error(`账号正在登录;先发送 codex-login-cancel ${Z.name}`);if(L8($,!0))throw Error("账号正在使用中;请先结束使用该账号的会话或委派任务,额度及模型查询结束后重试");let J=this.read(),Q=this.home($),Y;try{Y=j8(Q)}catch(X){if(X.code!=="ENOENT")throw X}if(Y){if(Y.isSymbolicLink()||!Y.isDirectory())throw Error("额外账号目录不是独立目录,拒绝删除");if(B8(this.defaultHome)){let X=nP(J4(Q),J4(this.defaultHome));if(!X||!iP(X)&&X!==".."&&!X.startsWith(`..${oP}`))throw Error("额外账号目录包含默认认证目录,拒绝删除")}try{cP(Q,{recursive:!0})}catch(X){throw Error(`账号文件删除失败,账号记录已保留;${X}`)}}J.accounts=J.accounts.filter((X)=>X.id!==$);let V=0;for(let[X,z]of Object.entries(J.selections)){if(z!==$)continue;delete J.selections[X],V++}try{a(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[$]:l}preferred($){let Z=this.read().selections;return Object.prototype.hasOwnProperty.call(Z,$)?Z[$]:null}selectAuto($){let Z=this.read();delete Z.selections[$],a(this.stateFile,Z)}select($,Z){this.get(Z);let J=this.read();Object.defineProperty(J.selections,$,{value:Z,enumerable:!0,writable:!0,configurable:!0}),a(this.stateFile,J)}recordLogin($,Z){let J=this.read();if($===l){this.defaultLoginRevision=T5();return}let Q=J.accounts.find((Y)=>Y.id===$);if(!Q)throw Error("登录完成时账号记录已不存在");Object.assign(Q,{email:Z.email,planType:Z.planType,revision:T5()}),a(this.stateFile,J)}home($=l){return $===l?this.defaultHome:e$(this.root,this.get($).id)}revision($){let Z=this.get($);return JSON.stringify([this.home($),Z.revision??null])}prepareHome($){let Z=this.home($);if($===l)return Z;let J;try{J=j8(Z)}catch(V){if(V.code!=="ENOENT")throw V}if(J?.isSymbolicLink())throw Error("额外账号目录不能是软链接");if(E5(Z,{recursive:!0,mode:448}),E5(this.defaultHome,{recursive:!0,mode:448}),J4(Z)===J4(this.defaultHome))throw Error("额外账号不能使用默认认证目录");let Q;try{Q=j8(e$(Z,"auth.json"))}catch(V){if(V.code!=="ENOENT")throw V}if(Q?.isSymbolicLink()||Q&&!Q.isFile())throw Error("额外账号的 auth.json 必须为独立文件");try{uP(e$(this.defaultHome,"config.toml"),"",{flag:"wx",mode:384})}catch(V){if(V.code!=="EEXIST")throw V}for(let V of sP){let X=e$(this.defaultHome,V);E5(X,{recursive:!0,mode:448}),this.link(X,e$(Z,V),!0)}let Y=new Set([...tP,...pP(this.defaultHome).filter((V)=>V.endsWith(".config.toml"))]);for(let V of Y){let X=e$(this.defaultHome,V);if(B8(X))this.link(X,e$(Z,V),!1)}return Z}link($,Z,J){let Q;try{Q=j8(Z)}catch(Y){if(Y.code!=="ENOENT")throw Y}if(Q){if(!Q.isSymbolicLink()||J4(Z)!==J4($))throw Error(`Codex 共享路径已被替换或指向其他位置:${Z}`);return}lP($,Z,J&&process.platform==="win32"?"junction":J?"dir":"file")}env($,Z,J=!0,Q=!1){if(!Q&&M1($))throw Error("该 Codex 账号正在登录,请等待授权完成");let Y=J?this.prepareHome($):this.home($),V={...Z,CODEX_HOME:Y};if($!==l){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($),$===l?[]:["-c",'cli_auth_credentials_store="file"',"-c",'forced_login_method="chatgpt"']}fingerprint($){let Z=e$(this.home($),"auth.json");if(!B8(Z))return null;let Q=JSON.parse(BX(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 mP("sha256").update(JSON.stringify([Q.account_id,V.sub])).digest("hex")}}function O1($,Z,J=!0){if(_X.set($,Z),!_8.has($))$.once("exit",()=>_8.delete($));_8.set($,{id:Z,ownsNativeProcess:J})}function L8($,Z=!1){return[..._8].some(([J,Q])=>Q.id===$&&(Q.ownsNativeProcess||Z)&&J.isAlive())}function M1($){return j9.has($)}function LX($){if(j9.has($))throw Error("该账号已有登录任务");if(L8($))throw Error("该 Codex 账号正在使用中");let Z=Symbol($);return j9.set($,Z),()=>{if(j9.get($)===Z)j9.delete($)}}function j$($){return $?_X.get($)??l:l}var l="default",sP,tP,v,_X,_8,j9;var j0=R(()=>{H0();x0();sP=["sessions","archived_sessions","skills","rules","prompts","plugins","memories","generated_images","thread-writer-locks"],tP=["config.toml","AGENTS.md","AGENTS.override.md","hooks.json","history.jsonl","session_index.jsonl","installation_id"];v=new jX,_X=new WeakMap,_8=new Map;j9=new Map});import{readFileSync as rP}from"node:fs";import{homedir as qX}from"node:os";function PX($){return $.replace(/^~(?=\/|$)/,qX())}function eP($){let Z={_:{}},J="_";for(let Q of $.split(`
63
+ `)){let Y=$q(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 z=X[2].trim(),H=z.startsWith('"')&&z.endsWith('"'),G=z.startsWith("'")&&z.endsWith("'");if(H||G){if(z=z.slice(1,-1),H)z=z.replace(/\\([\\"])/g,"$1")}Z[J][X[1]]=z}}return Z}function $q($){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 _9(){let $;try{$=rP(v0,"utf8")}catch(M){throw process.stderr.write(`lodestar: cannot read config at ${v0}
64
64
  `+" → 运行 `lodestar-setup` 走交互式向导生成 (Feishu / Codex / 工作目录)\n"+` → 或手写: 设 LODESTAR_CONFIG=/path/to/config.toml 覆盖默认路径
65
65
  `+` [feishu]
66
66
  app_id = "cli_xxx"
67
67
  app_secret = "xxx"
68
68
 
69
- `),M}let Z=iL($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${v0} is missing [feishu].app_id / [feishu].app_secret`);let Y=_X(Z.runtime?.projects_root??PX()),V={codex:!1,claude:!1,dsh:!1},X=Z["runtime.agent_auto_update"],z=Z.runtime?.agent_auto_update;if(z!==void 0){if(X)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(z!=="true"&&z!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${z}"`);for(let M of["codex","claude","dsh"])V[M]=z==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
70
- `)}else if(X)for(let[M,O]of Object.entries(X)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(O!=="true"&&O!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${O}"`);V[M]=O==="true"}let H=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(H!=="bucket"&&H!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let G=H,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 j=Number.parseInt(K,10);if(!Number.isFinite(j)||j<=0||j>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let _=(M)=>{let O=Z[M]??{},R={};for(let[w,T]of Object.entries(O))if(typeof T==="string"&&T.length>0)R[w]=T;return R},D=()=>{let M={};for(let[O,R]of Object.entries(Z)){if(!O.startsWith("claude.models."))continue;let T=O.slice(14).trim();if(!T)continue;let f={};for(let[u,C]of Object.entries(R)){if(typeof C!=="string"||C.length===0)continue;if(u.trim()==="model")f.model=C}M[T]=f}return M},L=()=>{let M={},O="projects.";for(let[R,w]of Object.entries(Z)){if(!R.startsWith("projects."))continue;let T=R.slice(9).trim();if(!T)continue;let f={};for(let[u,C]of Object.entries(w)){if(typeof C!=="string"||C.length===0)continue;switch(u.trim()){case"cwd":f.cwd=C;break;case"setting_sources":f.settingSources=C;break;case"strict_mcp":f.strictMcp=C==="true";break;case"tools":f.tools=C;break;case"load_project_mcp":f.loadProjectMcp=C==="true";break}}M[T]=f}return M},P=()=>{let M={},O="token_source.";for(let[R,w]of Object.entries(Z)){if(!R.startsWith("token_source."))continue;let T=R.slice(13).trim();if(!T)continue;let f={};for(let[u,C]of Object.entries(w)){if(typeof C!=="string")continue;let g=u.trim();if(g==="enabled"){if(C!=="true"&&C!=="false")throw Error(`[${R}].enabled 必须为 true 或 false`);f.enabled=C==="true"}else if(g==="default")f.default=C==="true";else if(g==="agent"||g==="display"||g==="auth"||g==="base_url"||g==="auth_token"||g==="api_key"||g==="management_token"||g==="management_user_id"||g==="management_url"||g==="billing_source"||g==="bin"||g==="model"||g==="effort"||g==="models"||g==="hidden_models"||g==="custom_models"||g==="slots"||g==="usage")f[g]=C}M[T]=f}return M},F=_("codex.env"),U=_("claude.env"),A=Z.claude?.bin?_X(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Q},runtime:{projects_root:Y,live_elapsed:G,agent_auto_update:V},notify:{bind:W,port:j},codex:{env:F},claude:{bin:A,env:U,models:D()},projects:L(),token_sources:P()}}function LX(){m.token_sources=j9().token_sources}var m;var f0=N(()=>{H0();m=j9()});function q0($){return typeof $==="string"&&$?$:void 0}function o($){return $!=null&&typeof $==="object"?$:null}function $1($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function P8($){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 oL($){let Z=$.slice(0,S5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function sL($){let Z=o($);if(!Z)return null;let J=o(Z.event),Q=o(Z.payload);return o(Z.item)??o(Z.responseItem)??o(Z.rawItem)??o(J?.item)??o(J?.responseItem)??o(J?.rawItem)??o(Q?.item)??o(Q?.responseItem)??o(Q?.rawItem)??(_9(Z.type)?Z:null)??(J&&_9(J.type)?J:null)??(Q&&_9(Q.type)?Q:null)}function tL($){let Z=[],J=new WeakSet,Q=(Y,V,X)=>{if(Z.length>=S5||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 z of Object.keys(Y)){if(Z.length>=S5)return;let H=V?`${V}.${z}`:z;Z.push(H),Q(Y[z],H,X+1)}};return Q($,"",0),Z}function C5($){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>x5)return`${Y.slice(0,x5)}...<truncated ${Y.length-x5} 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>E5)return`${J.slice(0,E5)}...<truncated ${J.length-E5} chars>`;return J}function $$($,Z){let J=o(Z),Q=J?o(J.params):null,Y=J?o(J.item)??o(Q?.item):null,V=J?q0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${$1(V)}`,`rootKeys=${P8(J)}`,`itemKeys=${P8(Y)}`,`payload=${C5(Z)}`].join(" "))}function b5($,Z,J){let Q=o(Z),Y=sL(Z),V=[`phase=${$1(J.phase??"event")}`,`method=${$1($)}`,`sourceMethod=${$1(J.sourceMethod)}`,`sourceType=${$1(J.sourceType)}`,`sessionId=${$1(J.sessionId)}`,`threadId=${$1(J.threadId)}`,`turnId=${$1(J.turnId)}`,`itemId=${$1(J.itemId)}`].join(" ");if(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${P8(Q)} itemKeys=${P8(Y)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${oL(tL(Z))}`),Y)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${C5(Y)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${C5(Z)}`)}function _9($){if(typeof $!=="string")return null;return aL.has($)?$:null}function rL($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||qX.has(Z))return"end";return"event"}function k5($,Z){return DX($,o(Z)??{})}function w5($){let Z=o($);if(!Z)return null;let J=q0(Z.method)??q0(Z.type)??"raw_message";return DX(J,Z)}function DX($,Z){let J=o(Z.payload),Q=[Z,o(Z.event),J,o(Z.item),o(Z.responseItem),o(Z.rawItem)].filter((H)=>H!=null),Y=null;for(let H of Q)if(Y=_9(H.type),Y)break;if(!qX.has($)&&!Y)return null;let V=o(Z.item)??o(Z.responseItem)??o(Z.rawItem),X=Y==="compacted"&&J?J:V&&_9(V.type)?V:Z,z=o(X.item)??o(X.responseItem)??o(X.rawItem)??V??{};return{...X,threadId:q0(X.threadId)??q0(X.thread_id)??q0(Z.threadId)??q0(Z.thread_id),turnId:q0(X.turnId)??q0(X.turn_id)??q0(Z.turnId)??q0(Z.turn_id),itemId:q0(X.itemId)??q0(X.item_id)??q0(z.id)??q0(z.itemId)??q0(z.item_id),timestamp:q0(Z.timestamp)??q0(X.timestamp),recordType:q0(Z.type),phase:rL(Y,$),sourceMethod:$,sourceType:Y??$}}var qX,aL,E5=200000,x5=50000,S5=400;var v5=N(()=>{h();qX=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),aL=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function P9($){return $!=null&&typeof $==="object"?$:null}function Z1($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function FX($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function L8($,Z){return $?Z1($[Z]):void 0}function Q4($){let Z=P9($);if(!Z)return null;let J=P9(Z.inputTokensDetails)??P9(Z.input_tokens_details),Q=P9(Z.outputTokensDetails)??P9(Z.output_tokens_details),Y={total_tokens:Z1(Z.totalTokens??Z.total_tokens),input_tokens:Z1(Z.inputTokens??Z.input_tokens),output_tokens:Z1(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:Z1(Z.reasoningOutputTokens??Z.reasoning_output_tokens??L8(Q,"reasoningTokens")??L8(Q,"reasoning_tokens")),cache_creation_input_tokens:Z1(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:Z1(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??L8(J,"cachedTokens")??L8(J,"cached_tokens"))};return FX(Y)?Y:null}function y5($,Z){let J=(Y)=>{let V=Z1($?.[Y]),X=Z1(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 FX(Q)?Q:null}function f5($){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 UX($){let Z=$.trim();if(Z.length<2)return Z;let J=q8[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 I5($){let Z=$q(String($??"")),J=Z.split(`
69
+ `),M}let Z=eP($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${v0} is missing [feishu].app_id / [feishu].app_secret`);let Y=PX(Z.runtime?.projects_root??qX()),V={codex:!1,claude:!1,dsh:!1},X=Z["runtime.agent_auto_update"],z=Z.runtime?.agent_auto_update;if(z!==void 0){if(X)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(z!=="true"&&z!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${z}"`);for(let M of["codex","claude","dsh"])V[M]=z==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
70
+ `)}else if(X)for(let[M,O]of Object.entries(X)){if(M!=="codex"&&M!=="claude"&&M!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${M}"`);if(O!=="true"&&O!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${M} must be true or false, got "${O}"`);V[M]=O==="true"}let H=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(H!=="bucket"&&H!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let G=H,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 j=Number.parseInt(K,10);if(!Number.isFinite(j)||j<=0||j>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let _=(M)=>{let O=Z[M]??{},T={};for(let[k,E]of Object.entries(O))if(typeof E==="string"&&E.length>0)T[k]=E;return T},D=()=>{let M={};for(let[O,T]of Object.entries(Z)){if(!O.startsWith("claude.models."))continue;let E=O.slice(14).trim();if(!E)continue;let f={};for(let[d,S]of Object.entries(T)){if(typeof S!=="string"||S.length===0)continue;if(d.trim()==="model")f.model=S}M[E]=f}return M},P=()=>{let M={},O="projects.";for(let[T,k]of Object.entries(Z)){if(!T.startsWith("projects."))continue;let E=T.slice(9).trim();if(!E)continue;let f={};for(let[d,S]of Object.entries(k)){if(typeof S!=="string"||S.length===0)continue;switch(d.trim()){case"cwd":f.cwd=S;break;case"setting_sources":f.settingSources=S;break;case"strict_mcp":f.strictMcp=S==="true";break;case"tools":f.tools=S;break;case"load_project_mcp":f.loadProjectMcp=S==="true";break}}M[E]=f}return M},L=()=>{let M={},O="token_source.";for(let[T,k]of Object.entries(Z)){if(!T.startsWith("token_source."))continue;let E=T.slice(13).trim();if(!E)continue;let f={};for(let[d,S]of Object.entries(k)){if(typeof S!=="string")continue;let g=d.trim();if(g==="enabled"){if(S!=="true"&&S!=="false")throw Error(`[${T}].enabled 必须为 true 或 false`);f.enabled=S==="true"}else if(g==="default")f.default=S==="true";else if(g==="agent"||g==="display"||g==="auth"||g==="base_url"||g==="auth_token"||g==="api_key"||g==="management_token"||g==="management_user_id"||g==="management_url"||g==="billing_source"||g==="bin"||g==="model"||g==="effort"||g==="models"||g==="hidden_models"||g==="custom_models"||g==="slots"||g==="usage")f[g]=S}M[E]=f}return M},F=_("codex.env"),U=_("claude.env"),A=Z.claude?.bin?PX(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Q},runtime:{projects_root:Y,live_elapsed:G,agent_auto_update:V},notify:{bind:W,port:j},codex:{env:F},claude:{bin:A,env:U,models:D()},projects:P(),token_sources:L()}}function DX(){m.token_sources=_9().token_sources}var m;var f0=R(()=>{H0();m=_9()});import{spawn as Zq}from"cross-spawn";import{mkdtemp as Jq,rm as FX,writeFile as Qq}from"node:fs/promises";import{tmpdir as Yq}from"node:os";import{join as UX}from"node:path";function Xq($){if(!$||typeof $!=="object"||Array.isArray($))throw Error("Codex raw model catalog is not an object");let Z=structuredClone($);if(!Array.isArray(Z.models)||!Z.models.length)throw Error("Codex raw model catalog has no models");for(let J of Z.models){if(!J||typeof J!=="object"||typeof J.slug!=="string"||!J.slug)throw Error("Codex raw model catalog contains an invalid model");if(!Array.isArray(J.experimental_supported_tools)||J.experimental_supported_tools.some((Q)=>typeof Q!=="string"))throw Error(`Codex raw model ${J.slug} has invalid experimental_supported_tools`);J.experimental_supported_tools=J.experimental_supported_tools.filter((Q)=>!Vq.has(Q))}return Z}function zq($){let Z=[],J=$.trim().split(`
71
+ `);for(let Q of J){let Y=/^([a-z0-9_.]+)\s+(.+?)\s+(true|false)\s*$/.exec(Q);if(!Y)throw Error("Codex feature catalog returned an invalid row");if(Y[2]!=="removed"&&["send_message_to_user_async","send_async_message"].includes(Y[1]))Z.push(Y[1])}return Z}async function MX($,Z){$.signal.throwIfAborted();let J=`Codex ${Z.join(" ")}`,Q=Zq($.binary,[...Z,...$.configArgs],{cwd:$.workDir,env:$.env,shell:!1,stdio:["ignore","pipe","pipe"],windowsHide:!0}),Y=[],V=[],X=0,z,H,G=(P)=>{if(z)return;if(z??=P,Q.pid)Q.kill("SIGTERM"),H=setTimeout(()=>{Q.kill("SIGKILL")},3000)},W=()=>G($.signal.reason instanceof Error?$.signal.reason:Error("Codex model catalog preparation cancelled"));$.signal.addEventListener("abort",W,{once:!0});let K=setTimeout(()=>G(Error(`${J} exceeded 30 seconds`)),30000),j=new Promise((P)=>{Q.on("error",(L)=>{z??=L}),Q.stdout.on("data",(L)=>{if(X+=L.length,X>33554432)G(Error("Codex raw model catalog exceeds 32 MiB"));else Y.push(L)}),Q.stderr.on("data",(L)=>{V.push(L)}),Q.once("close",(L)=>P(L))});if($.signal.aborted)W();let _;try{_=await j}finally{if(clearTimeout(K),H)clearTimeout(H);$.signal.removeEventListener("abort",W)}let D=Buffer.concat(V).toString("utf8").trim();if(D)B(`${J}[stderr]: ${D}`);if(z)throw z;if(_!==0)throw Error(`${J} failed (exit ${_}): ${D||"no diagnostic"}`);if(/ERROR[^\n]*(?:models_manager|model_catalog)|(?:models_manager|model_catalog)[^\n]*(?:failed|error)/i.test(D))throw Error(`Codex model catalog export reported an upstream failure: ${D}`);return $.signal.throwIfAborted(),Buffer.concat(Y).toString("utf8")}async function OX($){let Z=await Promise.allSettled([MX($,["debug","models"]),MX($,["features","list"])]),J=Z.filter((G)=>G.status==="rejected");if(J.length)throw AggregateError(J.map((G)=>G.reason),J.map((G)=>String(G.reason)).join("; "));let[Q,Y]=Z.map((G)=>G.value),V=Xq(JSON.parse(Q)),X=zq(Y),z=await Jq(UX(Yq(),"lodestar-codex-input-policy-")),H=UX(z,"models.json");try{return await Qq(H,JSON.stringify(V),{mode:384}),$.signal.throwIfAborted(),{path:H,disabledFeatures:X,dispose:()=>FX(z,{recursive:!0,force:!0})}}catch(G){throw await FX(z,{recursive:!0,force:!0}),G}}var Vq;var AX=R(()=>{h();Vq=new Set(["request_user_input","request_user_input_async","send_user_message_async","send_message_to_user_async"])});function q0($){return typeof $==="string"&&$?$:void 0}function o($){return $!=null&&typeof $==="object"?$:null}function $1($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function P8($){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 Gq($){let Z=$.slice(0,C5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function Wq($){let Z=o($);if(!Z)return null;let J=o(Z.event),Q=o(Z.payload);return o(Z.item)??o(Z.responseItem)??o(Z.rawItem)??o(J?.item)??o(J?.responseItem)??o(J?.rawItem)??o(Q?.item)??o(Q?.responseItem)??o(Q?.rawItem)??(L9(Z.type)?Z:null)??(J&&L9(J.type)?J:null)??(Q&&L9(Q.type)?Q:null)}function Kq($){let Z=[],J=new WeakSet,Q=(Y,V,X)=>{if(Z.length>=C5||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 z of Object.keys(Y)){if(Z.length>=C5)return;let H=V?`${V}.${z}`:z;Z.push(H),Q(Y[z],H,X+1)}};return Q($,"",0),Z}function b5($){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>S5)return`${Y.slice(0,S5)}...<truncated ${Y.length-S5} 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>x5)return`${J.slice(0,x5)}...<truncated ${J.length-x5} chars>`;return J}function $$($,Z){let J=o(Z),Q=J?o(J.params):null,Y=J?o(J.item)??o(Q?.item):null,V=J?q0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${$1(V)}`,`rootKeys=${P8(J)}`,`itemKeys=${P8(Y)}`,`payload=${b5(Z)}`].join(" "))}function k5($,Z,J){let Q=o(Z),Y=Wq(Z),V=[`phase=${$1(J.phase??"event")}`,`method=${$1($)}`,`sourceMethod=${$1(J.sourceMethod)}`,`sourceType=${$1(J.sourceType)}`,`sessionId=${$1(J.sessionId)}`,`threadId=${$1(J.threadId)}`,`turnId=${$1(J.turnId)}`,`itemId=${$1(J.itemId)}`].join(" ");if(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${P8(Q)} itemKeys=${P8(Y)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${Gq(Kq(Z))}`),Y)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${b5(Y)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${b5(Z)}`)}function L9($){if(typeof $!=="string")return null;return Hq.has($)?$:null}function Bq($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||NX.has(Z))return"end";return"event"}function w5($,Z){return RX($,o(Z)??{})}function v5($){let Z=o($);if(!Z)return null;let J=q0(Z.method)??q0(Z.type)??"raw_message";return RX(J,Z)}function RX($,Z){let J=o(Z.payload),Q=[Z,o(Z.event),J,o(Z.item),o(Z.responseItem),o(Z.rawItem)].filter((H)=>H!=null),Y=null;for(let H of Q)if(Y=L9(H.type),Y)break;if(!NX.has($)&&!Y)return null;let V=o(Z.item)??o(Z.responseItem)??o(Z.rawItem),X=Y==="compacted"&&J?J:V&&L9(V.type)?V:Z,z=o(X.item)??o(X.responseItem)??o(X.rawItem)??V??{};return{...X,threadId:q0(X.threadId)??q0(X.thread_id)??q0(Z.threadId)??q0(Z.thread_id),turnId:q0(X.turnId)??q0(X.turn_id)??q0(Z.turnId)??q0(Z.turn_id),itemId:q0(X.itemId)??q0(X.item_id)??q0(z.id)??q0(z.itemId)??q0(z.item_id),timestamp:q0(Z.timestamp)??q0(X.timestamp),recordType:q0(Z.type),phase:Bq(Y,$),sourceMethod:$,sourceType:Y??$}}var NX,Hq,x5=200000,S5=50000,C5=400;var y5=R(()=>{h();NX=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),Hq=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function P9($){return $!=null&&typeof $==="object"?$:null}function Z1($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function TX($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function q8($,Z){return $?Z1($[Z]):void 0}function Q4($){let Z=P9($);if(!Z)return null;let J=P9(Z.inputTokensDetails)??P9(Z.input_tokens_details),Q=P9(Z.outputTokensDetails)??P9(Z.output_tokens_details),Y={total_tokens:Z1(Z.totalTokens??Z.total_tokens),input_tokens:Z1(Z.inputTokens??Z.input_tokens),output_tokens:Z1(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:Z1(Z.reasoningOutputTokens??Z.reasoning_output_tokens??q8(Q,"reasoningTokens")??q8(Q,"reasoning_tokens")),cache_creation_input_tokens:Z1(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:Z1(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??q8(J,"cachedTokens")??q8(J,"cached_tokens"))};return TX(Y)?Y:null}function f5($,Z){let J=(Y)=>{let V=Z1($?.[Y]),X=Z1(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 TX(Q)?Q:null}function h5($){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 EX($){let Z=$.trim();if(Z.length<2)return Z;let J=D8[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 g5($){let Z=_q(String($??"")),J=Z.split(`
71
72
  `,1)[0]?.trim()??"",Y=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),V=Y?Z.split(`
72
73
  `).slice(1).join(`
73
- `).trimStart():Z;return{description:Y,command:V||Z}}function Y4($,Z=60){let{description:J,command:Q}=I5($);if(J)return J;return eL(Q).replace(/\s+/g," ").trim().slice(0,Z)}function eL($){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 $q($){let Z=$.replace(/\r\n/g,`
74
- `).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=Jq(J[1]);return h5(Y||Z)}let Q=Zq(Z);if(Q)return Q;return h5(Z)}function Zq($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=UX(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 h5(UX(Y[2]));if(Q=Y[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function Jq($){let Z=$.trim();if(Z.length<2)return Z;let J=q8[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,`
75
- `)}function h5($){let Z=$.trim(),J=Z[0];if(!q8[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!Qq(Q,J))return Z;if(J!=='"')return Q.replace(/'\s*$/,"");return Q.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
76
- `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(X,z)=>` $(${z})`)}function Qq($,Z){let J=q8[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 q8;var D8=N(()=>{q8={'"':'"',"'":"'","“":"”"}});function MX($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function S($){return $ instanceof Error?$.message:String($)}function S0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as OX}from"node:path";function Yq($){return $.kind==="fresh"?null:$.source.provider}function M0($,Z,J){let Q=Yq($);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"||!OX($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!OX(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 r1=()=>{};import{existsSync as Vq,readFileSync as Xq}from"node:fs";function AX($,Z){return`${$}:${Z}`}function zq(){if(!Vq(d3))return;try{let $=JSON.parse(Xq(d3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");L9=new Set($.ids)}catch($){g5=$ instanceof Error?$:Error(String($))}}function NX(){if(g5)throw Error(`delegated-agent session registry is unavailable: ${g5.message}`)}function RX($,Z){NX();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Q=AX($,J);if(L9.has(Q))return;let Y=new Set(L9);Y.add(Q),a(d3,{version:1,ids:[...Y].sort()}),L9=Y}function V4($,Z){return NX(),L9.has(AX($,Z))}var L9,g5=null;var q9=N(()=>{H0();x0();L9=new Set;zq()});function F8($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.hasCredits!=="boolean"||typeof Z.unlimited!=="boolean")return null;let J=null;if(Z.balance!=null){if(typeof Z.balance!=="number"&&!(typeof Z.balance==="string"&&/^\d+(?:\.\d+)?$/.test(Z.balance.trim())))return null;if(J=Number(Z.balance),!Number.isFinite(J)||J<0||J>Number.MAX_SAFE_INTEGER)return null}if(!Z.unlimited&&J!==null&&Z.hasCredits!==J>0)return null;return{hasCredits:Z.hasCredits,unlimited:Z.unlimited,balance:J}}function e1($){return $==null?"unknown":$.hasCredits||$.unlimited?"available":"empty"}function TX($,Z){if(!$||!Z||e1(Z)!=="available")return!1;return e1($)==="empty"||!$.unlimited&&Z.unlimited||!$.unlimited&&$.balance!==null&&Z.balance!==null&&Z.balance>$.balance}function p5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function Wq($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function $2($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$,Q=!("limitId"in J)||J.limitId===$.defaultLimitId?$.ordinaryUsageAllowed:void 0;return{...J,ordinaryUsageAllowed:Q,fiveHour:p5($.subscriptionType,J.fiveHour)}}function c5($){if($.spendControlReached===!0)return{state:"exhausted",reason:"已达到上游消费限制"};if($.rateLimitReachedType&&$.rateLimitReachedType!=="rate_limit_reached")return{state:"exhausted",reason:`上游额度限制:${$.rateLimitReachedType}`};let Z=[$.fiveHour,$.weekly].filter((V)=>V!==null),J=Z.some((V)=>V.percent!==null&&V.percent>=100),Q=J||$.ordinaryUsageAllowed===!1||$.rateLimitReachedType==="rate_limit_reached",Y=e1($.credits);if(Q&&Y==="empty")return{state:"exhausted",reason:J?"额度耗尽":"套餐内额度暂不可用,且无可用积分"};if(Z.some((V)=>V.percent===null||!Number.isFinite(V.percent)||V.percent<0||V.percent>100))return{state:"miss",reason:"额度百分比 MISS"};if(Q)return Y==="available"?{state:"credits"}:{state:"miss",reason:`${J?"订阅额度已用完":"套餐内额度暂不可用"},积分 MISS`};return{state:"subscription"}}function Z2($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=$2($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function xX($,Z){let J=$2($,Z).weekly,Q=$.readStartedAt??$.fetchedAt,Y=J?.resetsAt?.getTime();return J?.percent===0&&J.durationMins===10080&&Number.isFinite(Q)&&Number.isFinite($.fetchedAt)&&Q<=$.fetchedAt&&Y!=null&&Y>=Math.floor(Q/1000)*1000+m5&&Y<=Math.floor($.fetchedAt/1000)*1000+m5}function SX($,Z,J){let Q=$2($,Z).weekly?.resetsAt?.getTime();return Q!=null&&Q-m5<=J}function U8($,Z){let J=Number($.funding==="credits")-Number(Z.funding==="credits");if(J)return J;if($.funding==="credits"&&Z.funding==="credits"){let Y=$.credits,V=Z.credits;return Number(V.unlimited)-Number(Y.unlimited)||Number(Y.balance===null)-Number(V.balance===null)||(Y.balance!==null&&V.balance!==null?V.balance-Y.balance:0)||$.account.id.localeCompare(Z.account.id)}let Q=(Y)=>Y.priority==="expiring"?1:0;return Q(Z)-Q($)||($.priority==="expiring"?$.hours-Z.hours:Z.score-$.score)||(Z.availableNow??0)-($.availableNow??0)||$.account.id.localeCompare(Z.account.id)}function D9($,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=Wq($.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=$2($,Z),z=c5(X);if(z.state==="miss")return{...Y,reason:z.reason};if(z.state==="exhausted"){let P=[X.fiveHour,X.weekly].filter((U)=>U!==null&&U.percent!==null&&U.percent>=100),F=P.map((U)=>U.resetsAt?.getTime()).filter((U)=>U!=null&&Number.isFinite(U)&&U>J);return{...Y,state:"exhausted",reason:z.reason,...F.length===P.length&&F.length?{retryAt:Math.max(...F)}:{}}}if(z.state==="credits")return{...Y,state:"ready",funding:"credits",credits:X.credits};let H=X.weekly;if(!H||H.percent===null)return{...Y,reason:"周额度 MISS"};let G=H.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Y,reason:"周重置时间 MISS 或已过期"};let W=V*(100-H.percent)/100,K=(G-J)/3600000,j=K-Gq,_=j>0?W/j:null,D=e1(X.credits);if(Q==="ultra"&&W<EX&&D!=="available"){if(D==="unknown")return{...Y,remaining:W,hours:K,weeklyScore:_,reason:"Ultra 周余量不足,积分 MISS"};return{...Y,state:"waiting",remaining:W,hours:K,weeklyScore:_,reason:`Ultra 至少需要 ${EX} 份周余量`,retryAt:G}}let L=j<=0?"expiring":void 0;if($.subscriptionType==="plus"){let P=X.fiveHour,F=Hq*(100-P.percent)/100,U=P.unreportedFull?5:((P.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(U)||U<=0)return{...Y,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:W,hours:K,priority:L,weeklyScore:_,fiveHourRemaining:F,fiveHourHours:U,availableNow:Math.min(W,F),score:_===null?null:Math.min(_,F/U)}}return{state:"ready",shares:V,remaining:W,hours:K,priority:L,weeklyScore:_,availableNow:W,score:_}}function M8($){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)}var Hq=0.15,EX=0.5,m5=604800000,Gq=5;var J2=()=>{};import{closeSync as Kq,existsSync as Bq,mkdirSync as jq,openSync as _q,readdirSync as Pq,readSync as Lq,statSync as A8,writeFileSync as qq}from"node:fs";import{homedir as l5}from"node:os";import{delimiter as CX,isAbsolute as bX,join as A1}from"node:path";import{EventEmitter as Dq}from"node:events";import{StringDecoder as kX}from"node:string_decoder";import{spawn as Fq}from"cross-spawn";function F9(){return W9("codex","codex")}function Uq(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([A1(l5(),".local","npm-global","bin"),A1(l5(),".local","bin"),A1(l5(),".bun","bin"),...(process.env.PATH??"").split(CX),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(CX)}function vX($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function Eq($){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 xq($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function Sq($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function _$($){return typeof $==="string"&&Q2.includes($)}function Cq($){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(!_$(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 u5($,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:d5($)}}return null}function bq($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function d5($){return{status:$.status,revisedPrompt:bq($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function yX($){if(!$||!Bq(wX))return null;let Z=null,J=[wX];while(J.length){let Q=J.pop(),Y;try{Y=Pq(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=A1(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 z=A8(X).mtimeMs;if(!Z||z>Z.mtimeMs)Z={path:X,mtimeMs:z}}catch(z){B(`codex-process: cannot stat Codex rollout ${X}: ${z instanceof Error?z.message:z}`)}}}return Z?.path??null}function gX($,Z,J=Mq){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let V=kq($,Z,J);if(V)return V;if(Y.length>2048){let X=mX($);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 kq($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=wq(Q);if(!Y)return null;let V=fX(Z??"unknown-thread"),X=fX(mX($)),z=A1(J,V),H=A1(z,`${X}.${Y.ext}`);try{return jq(z,{recursive:!0}),qq(H,Y.buffer),H}catch(G){return B(`codex-process: failed to write image generation result ${H}: ${G instanceof Error?G.message:G}`),null}}function mX($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function fX($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function wq($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=yq(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 z=vq(X)??Q;if(!z)return null;return{buffer:X,ext:z}}function vq($){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 yq($){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 hX($,Z,J){let Q=u5($,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:gX($,J),isError:$.status==="failed"}}return null}function O8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return S0(Z)}function IX($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function fq($,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 Y4(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 pX($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function hq($){let Z=pX($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function Iq($){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(`${S0(Q)}: ${X}`)}return J.join(`
77
- `)}var wX,Mq,Oq=30000,Aq=600000,Nq=5000,Rq=60000,Tq="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",Q2,U9="xhigh",X4,z4;var J1=N(()=>{f0();h();Z4();v5();D8();r1();q9();j0();J2();v5();wX=A1(y.defaultHome,"sessions"),Mq=A1(y.defaultHome,"generated_images");Q2=["none","minimal","low","medium","high","xhigh","max","ultra"];X4=class X4 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"}};z4=class z4 extends Dq{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 kX("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=F9(),J=[...xq($.allowDelegation!==!1),...$.apiProvider?Eq($.apiProvider):[...$.tokenSourceId==="codex-sub"?["-c",'model_provider="openai"']:[],...y.cliArgs($.codexAccountId??c)]];B(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:Uq(),...m.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q,V=$.apiProvider?{...Y,CODEX_HOME:y.defaultHome}:y.env($.codexAccountId??c,Y);if(this.proc=Fq(Z,J,Sq($.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,z)=>this.handleChildExit(X,z)),this.proc.on("close",(X,z)=>this.handleChildClose(X,z)),this.proc.on("error",(X)=>this.handleChildProcessError(X)),!$.apiProvider)O1(this,$.codexAccountId??c)}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(`
74
+ `).trimStart():Z;return{description:Y,command:V||Z}}function Y4($,Z=60){let{description:J,command:Q}=g5($);if(J)return J;return jq(Q).replace(/\s+/g," ").trim().slice(0,Z)}function jq($){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 _q($){let Z=$.replace(/\r\n/g,`
75
+ `).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=Pq(J[1]);return I5(Y||Z)}let Q=Lq(Z);if(Q)return Q;return I5(Z)}function Lq($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=EX(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 I5(EX(Y[2]));if(Q=Y[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function Pq($){let Z=$.trim();if(Z.length<2)return Z;let J=D8[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,`
76
+ `)}function I5($){let Z=$.trim(),J=Z[0];if(!D8[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!qq(Q,J))return Z;if(J!=='"')return Q.replace(/'\s*$/,"");return Q.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
77
+ `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(X,z)=>` $(${z})`)}function qq($,Z){let J=D8[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 D8;var F8=R(()=>{D8={'"':'"',"'":"'","“":"”"}});function xX($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function x($){return $ instanceof Error?$.message:String($)}function S0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as SX}from"node:path";function Dq($){return $.kind==="fresh"?null:$.source.provider}function M0($,Z,J){let Q=Dq($);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"||!SX($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!SX(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 e1=()=>{};import{existsSync as Fq,readFileSync as Uq}from"node:fs";function CX($,Z){return`${$}:${Z}`}function Mq(){if(!Fq(i3))return;try{let $=JSON.parse(Uq(i3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");q9=new Set($.ids)}catch($){m5=$ instanceof Error?$:Error(String($))}}function bX(){if(m5)throw Error(`delegated-agent session registry is unavailable: ${m5.message}`)}function kX($,Z){bX();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Q=CX($,J);if(q9.has(Q))return;let Y=new Set(q9);Y.add(Q),a(i3,{version:1,ids:[...Y].sort()}),q9=Y}function V4($,Z){return bX(),q9.has(CX($,Z))}var q9,m5=null;var D9=R(()=>{H0();x0();q9=new Set;Mq()});function U8($){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;if(typeof Z.hasCredits!=="boolean"||typeof Z.unlimited!=="boolean")return null;let J=null;if(Z.balance!=null){if(typeof Z.balance!=="number"&&!(typeof Z.balance==="string"&&/^\d+(?:\.\d+)?$/.test(Z.balance.trim())))return null;if(J=Number(Z.balance),!Number.isFinite(J)||J<0||J>Number.MAX_SAFE_INTEGER)return null}if(!Z.unlimited&&J!==null&&Z.hasCredits!==J>0)return null;return{hasCredits:Z.hasCredits,unlimited:Z.unlimited,balance:J}}function $2($){return $==null?"unknown":$.hasCredits||$.unlimited?"available":"empty"}function wX($,Z){if(!$||!Z||$2(Z)!=="available")return!1;return $2($)==="empty"||!$.unlimited&&Z.unlimited||!$.unlimited&&$.balance!==null&&Z.balance!==null&&Z.balance>$.balance}function c5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function Nq($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function Z2($,Z){let J=$.buckets?.find((Y)=>Y.limitName?.toLowerCase()===Z.toLowerCase()||Y.normalModelSlug===Z)??$,Q=!("limitId"in J)||J.limitId===$.defaultLimitId?$.ordinaryUsageAllowed:void 0;return{...J,ordinaryUsageAllowed:Q,fiveHour:c5($.subscriptionType,J.fiveHour)}}function l5($){if($.spendControlReached===!0)return{state:"exhausted",reason:"已达到上游消费限制"};if($.rateLimitReachedType&&$.rateLimitReachedType!=="rate_limit_reached")return{state:"exhausted",reason:`上游额度限制:${$.rateLimitReachedType}`};let Z=[$.fiveHour,$.weekly].filter((V)=>V!==null),J=Z.some((V)=>V.percent!==null&&V.percent>=100),Q=J||$.ordinaryUsageAllowed===!1||$.rateLimitReachedType==="rate_limit_reached",Y=$2($.credits);if(Q&&Y==="empty")return{state:"exhausted",reason:J?"额度耗尽":"套餐内额度暂不可用,且无可用积分"};if(Z.some((V)=>V.percent===null||!Number.isFinite(V.percent)||V.percent<0||V.percent>100))return{state:"miss",reason:"额度百分比 MISS"};if(Q)return Y==="available"?{state:"credits"}:{state:"miss",reason:`${J?"订阅额度已用完":"套餐内额度暂不可用"},积分 MISS`};return{state:"subscription"}}function J2($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=Z2($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function yX($,Z){let J=Z2($,Z).weekly,Q=$.readStartedAt??$.fetchedAt,Y=J?.resetsAt?.getTime();return J?.percent===0&&J.durationMins===10080&&Number.isFinite(Q)&&Number.isFinite($.fetchedAt)&&Q<=$.fetchedAt&&Y!=null&&Y>=Math.floor(Q/1000)*1000+p5&&Y<=Math.floor($.fetchedAt/1000)*1000+p5}function fX($,Z,J){let Q=Z2($,Z).weekly?.resetsAt?.getTime();return Q!=null&&Q-p5<=J}function M8($,Z){let J=Number($.funding==="credits")-Number(Z.funding==="credits");if(J)return J;if($.funding==="credits"&&Z.funding==="credits"){let Y=$.credits,V=Z.credits;return Number(V.unlimited)-Number(Y.unlimited)||Number(Y.balance===null)-Number(V.balance===null)||(Y.balance!==null&&V.balance!==null?V.balance-Y.balance:0)||$.account.id.localeCompare(Z.account.id)}let Q=(Y)=>Y.priority==="expiring"?1:0;return Q(Z)-Q($)||($.priority==="expiring"?$.hours-Z.hours:Z.score-$.score)||(Z.availableNow??0)-($.availableNow??0)||$.account.id.localeCompare(Z.account.id)}function F9($,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=Nq($.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=Z2($,Z),z=l5(X);if(z.state==="miss")return{...Y,reason:z.reason};if(z.state==="exhausted"){let L=[X.fiveHour,X.weekly].filter((U)=>U!==null&&U.percent!==null&&U.percent>=100),F=L.map((U)=>U.resetsAt?.getTime()).filter((U)=>U!=null&&Number.isFinite(U)&&U>J);return{...Y,state:"exhausted",reason:z.reason,...F.length===L.length&&F.length?{retryAt:Math.max(...F)}:{}}}if(z.state==="credits")return{...Y,state:"ready",funding:"credits",credits:X.credits};let H=X.weekly;if(!H||H.percent===null)return{...Y,reason:"周额度 MISS"};let G=H.resetsAt?.getTime();if(G==null||!Number.isFinite(G)||G<=J)return{...Y,reason:"周重置时间 MISS 或已过期"};let W=V*(100-H.percent)/100,K=(G-J)/3600000,j=K-Aq,_=j>0?W/j:null,D=$2(X.credits);if(Q==="ultra"&&W<vX&&D!=="available"){if(D==="unknown")return{...Y,remaining:W,hours:K,weeklyScore:_,reason:"Ultra 周余量不足,积分 MISS"};return{...Y,state:"waiting",remaining:W,hours:K,weeklyScore:_,reason:`Ultra 至少需要 ${vX} 份周余量`,retryAt:G}}let P=j<=0?"expiring":void 0;if($.subscriptionType==="plus"){let L=X.fiveHour,F=Oq*(100-L.percent)/100,U=L.unreportedFull?5:((L.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(U)||U<=0)return{...Y,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:W,hours:K,priority:P,weeklyScore:_,fiveHourRemaining:F,fiveHourHours:U,availableNow:Math.min(W,F),score:_===null?null:Math.min(_,F/U)}}return{state:"ready",shares:V,remaining:W,hours:K,priority:P,weeklyScore:_,availableNow:W,score:_}}function O8($){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)}var Oq=0.15,vX=0.5,p5=604800000,Aq=5;var Q2=()=>{};import{closeSync as Rq,existsSync as Tq,mkdirSync as Eq,openSync as xq,readdirSync as Sq,readSync as Cq,statSync as N8,writeFileSync as bq}from"node:fs";import{homedir as u5}from"node:os";import{delimiter as hX,isAbsolute as IX,join as A1}from"node:path";import{EventEmitter as kq}from"node:events";import{StringDecoder as gX}from"node:string_decoder";import{spawn as wq}from"cross-spawn";function U9(){return K9("codex","codex")}function vq(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([A1(u5(),".local","npm-global","bin"),A1(u5(),".local","bin"),A1(u5(),".bun","bin"),...(process.env.PATH??"").split(hX),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(hX)}function pX($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function pq($){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 cq($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function lq($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function _$($){return typeof $==="string"&&Y2.includes($)}function uq($){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(!_$(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 d5($,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:i5($)}}return null}function dq($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function i5($){return{status:$.status,revisedPrompt:dq($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function cX($){if(!$||!Tq(mX))return null;let Z=null,J=[mX];while(J.length){let Q=J.pop(),Y;try{Y=Sq(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=A1(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 z=N8(X).mtimeMs;if(!Z||z>Z.mtimeMs)Z={path:X,mtimeMs:z}}catch(z){B(`codex-process: cannot stat Codex rollout ${X}: ${z instanceof Error?z.message:z}`)}}}return Z?.path??null}function iX($,Z,J=yq){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let V=iq($,Z,J);if(V)return V;if(Y.length>2048){let X=nX($);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 iq($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=nq(Q);if(!Y)return null;let V=lX(Z??"unknown-thread"),X=lX(nX($)),z=A1(J,V),H=A1(z,`${X}.${Y.ext}`);try{return Eq(z,{recursive:!0}),bq(H,Y.buffer),H}catch(G){return B(`codex-process: failed to write image generation result ${H}: ${G instanceof Error?G.message:G}`),null}}function nX($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function lX($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function nq($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=oq(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 z=aq(X)??Q;if(!z)return null;return{buffer:X,ext:z}}function aq($){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 oq($){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 uX($,Z,J){let Q=d5($,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:iX($,J),isError:$.status==="failed"}}return null}function A8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return S0(Z)}function dX($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function sq($,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 Y4(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 aX($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function tq($){let Z=aX($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function rq($){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(`${S0(Q)}: ${X}`)}return J.join(`
78
+ `)}var mX,yq,fq=30000,hq=600000,Iq=5000,gq=60000,mq="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",Y2,M9="xhigh",X4,z4;var J1=R(()=>{f0();h();Z4();AX();y5();F8();e1();D9();j0();Q2();y5();mX=A1(v.defaultHome,"sessions"),yq=A1(v.defaultHome,"generated_images");Y2=["none","minimal","low","medium","high","xhigh","max","ultra"];X4=class X4 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"}};z4=class z4 extends kq{provider="codex";tokenSourceId;launchKind;proc=null;startupPromise=null;inputPolicyAbort=new AbortController;inputPolicyCatalog=null;stdoutBuf="";stderrBuf="";requestCounter=0;pending=new Map;serverRequests=new Map;alive=!0;expectedExit=!1;exitEventEmitted=!1;childExitCode=null;childExitSignal=null;exitPromise;resolveExit;opts;usesCustomDefaultModeInstructions=!1;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 gX("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((z)=>{this.resolveExit=z}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=U9(),J=$.apiProvider?pq($.apiProvider):[...$.tokenSourceId==="codex-sub"?["-c",'model_provider="openai"']:[],...v.cliArgs($.codexAccountId??l)],Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:vq(),...m.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q,V=$.apiProvider?{...Y,CODEX_HOME:v.defaultHome}:v.env($.codexAccountId??l,Y),X=(z)=>{if(this.expectedExit)throw Error("Codex startup cancelled");this.inputPolicyCatalog=z??null,this.spawnNative(Z,[...cq($.allowDelegation!==!1),...J,...z?["-c",`model_catalog_json=${JSON.stringify(z.path)}`,...z.disabledFeatures.flatMap((H)=>["--disable",H])]:[]],V)};if($.allowUserInput===!1)this.startupPromise=OX({binary:Z,configArgs:J,env:V,workDir:$.workDir,signal:this.inputPolicyAbort.signal}).then(async(z)=>{if(this.expectedExit)throw await z.dispose(),Error("Codex startup cancelled");X(z)}).catch((z)=>{throw this.alive=!1,this.emit("error",z instanceof Error?z:Error(String(z))),this.emitProcessExit(this.expectedExit?null:1,this.expectedExit?"SIGTERM":null),z}),this.startupPromise.catch(()=>{});else X();if(!$.apiProvider)O1(this,$.codexAccountId??l)}spawnNative($,Z,J){B(`codex-process: spawn ${$} app-server (cwd=${this.opts.workDir})`),this.proc=wq($,Z,lq(this.opts.workDir,J)),this.proc.stdout.on("data",(Q)=>this.onStdout(Q)),this.proc.stderr.on("data",(Q)=>this.onStderr(Q)),this.proc.stdin.on("error",(Q)=>this.handleStdinError(Q)),this.proc.on("exit",(Q,Y)=>this.handleChildExit(Q,Y)),this.proc.on("close",(Q,Y)=>this.handleChildClose(Q,Y)),this.proc.on("error",(Q)=>this.handleChildProcessError(Q))}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(`
78
79
  `))>=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(`
79
80
  `))}onStderr($){this.stderrBuf+=$.toString();let Z;while((Z=this.stderrBuf.indexOf(`
80
- `))>=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 X4(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=w5($);if(Z){let J=this.withSessionId(Z);b5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}$$("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=k5($,Z);if(J){let Q=this.withSessionId(J);b5($,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(_$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=Q4(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=Q4(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){$$("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){$$("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 $$("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 z=V==="failed"||!!X,H=V==="completed"&&!z&&!!Y;if(this.lastCompletedTurnId=H?Y:null,this.currentTurnId=null,V==="failed"&&Y&&vX(X?.message)&&this.scheduleCapacityRetry(X.message,Tq))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let G=z?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:G,is_error:z},this.emit("result",{subtype:G,is_error:z,...z&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Y&&M8(X)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:H&&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 $$("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}}$$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){$$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=u5(Z,this.opts.workDir);if(!J){$$("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){$$("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=hX(Z,this.opts.workDir,this.sessionId??void 0);if(!J){$$("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:d5(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)??S0(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"?u5($,this.opts.workDir):hX($,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:fq(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=O8($.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=O8($.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=pX($);for(let Y of Q){if(this.collabAgentSettled.has(Y))continue;if(this.collabAgentSettled.add(Y),!this.collabAgentNames.has(Y))this.collabAgentNames.set(Y,O8(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:IX($.prompt),description:hq($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:Iq($),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($)??O8(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:IX(J.prompt)};this.emit("bg_task_started",X);let z={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",z)}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 kX("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=yX(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=A8($).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??yX(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=A8($).size;if(Y<=this.rolloutReadOffset)return;let V=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=_q($,"r"),z=0;try{while(z<V){let H=Lq(X,Z,z,V-z,this.rolloutReadOffset+z);if(H===0)break;z+=H}}finally{Kq(X)}Z=Z.subarray(0,z),this.rolloutReadOffset+=z}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(`
81
- `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let V;try{V=JSON.parse(Y)}catch(H){B(`codex-process: image generation rollout JSON parse failed ${$}: ${H instanceof Error?H.message:H}`);continue}let X=V?.payload,z=X?.type;if(z!=="image_generation_end"&&z!=="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=gX($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&bX(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:d5({...$,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:$$("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($)+`
82
- `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=Oq){let Q=++this.requestCounter;return new Promise((Y,V)=>{let X=setTimeout(()=>{let H=this.pending.get(Q);if(!H)return;this.pending.delete(Q),H.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),z={resolve:Y,reject:V,method:$,timeout:X};this.pending.set(Q,z),this.write({id:Q,method:$,params:Z},(H)=>{if(this.pending.get(Q)!==z)return;this.pending.delete(Q),clearTimeout(X),V(Error(`codex app-server ${$} request write failed (id=${Q}): ${H.message}`,{cause:H}))})})}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||!bX(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(_$(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},Aq))?.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=A8(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(M0($,"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(" ")+`
81
+ `))>=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 X4(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=v5($);if(Z){let J=this.withSessionId(Z);k5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}$$("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=w5($,Z);if(J){let Q=this.withSessionId(J);k5($,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(_$(Q?.effort))this.lastEffort=Q.effort;if(Q?.collaborationMode)this.usesCustomDefaultModeInstructions=Q.collaborationMode.mode==="default"&&typeof Q.collaborationMode.settings?.developer_instructions==="string";return}case"thread/tokenUsage/updated":{let Q=Q4(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=Q4(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){$$("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){$$("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 $$("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 z=V==="failed"||!!X,H=V==="completed"&&!z&&!!Y;if(this.lastCompletedTurnId=H?Y:null,this.currentTurnId=null,V==="failed"&&Y&&pX(X?.message)&&this.scheduleCapacityRetry(X.message,mq))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let G=z?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:G,is_error:z},this.emit("result",{subtype:G,is_error:z,...z&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Y&&O8(X)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:H&&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 $$("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}}$$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){$$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=d5(Z,this.opts.workDir);if(!J){$$("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){$$("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=uX(Z,this.opts.workDir,this.sessionId??void 0);if(!J){$$("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:i5(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)??S0(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"?d5($,this.opts.workDir):uX($,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:sq(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=A8($.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=A8($.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=aX($);for(let Y of Q){if(this.collabAgentSettled.has(Y))continue;if(this.collabAgentSettled.add(Y),!this.collabAgentNames.has(Y))this.collabAgentNames.set(Y,A8(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:dX($.prompt),description:tq($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:rq($),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($)??A8(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:dX(J.prompt)};this.emit("bg_task_started",X);let z={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",z)}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 gX("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=cX(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=N8($).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??cX(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=N8($).size;if(Y<=this.rolloutReadOffset)return;let V=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=xq($,"r"),z=0;try{while(z<V){let H=Cq(X,Z,z,V-z,this.rolloutReadOffset+z);if(H===0)break;z+=H}}finally{Rq(X)}Z=Z.subarray(0,z),this.rolloutReadOffset+=z}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(`
82
+ `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let V;try{V=JSON.parse(Y)}catch(H){B(`codex-process: image generation rollout JSON parse failed ${$}: ${H instanceof Error?H.message:H}`);continue}let X=V?.payload,z=X?.type;if(z!=="image_generation_end"&&z!=="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=iX($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&IX(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:i5({...$,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:$$("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||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($)+`
83
+ `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=fq){let Q=++this.requestCounter;return new Promise((Y,V)=>{let X=setTimeout(()=>{let H=this.pending.get(Q);if(!H)return;this.pending.delete(Q),H.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),z={resolve:Y,reject:V,method:$,timeout:X};this.pending.set(Q,z),this.write({id:Q,method:$,params:Z},(H)=>{if(this.pending.get(Q)!==z)return;this.pending.delete(Q),clearTimeout(X),V(Error(`codex app-server ${$} request write failed (id=${Q}): ${H.message}`,{cause:H}))})})}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.startupPromise)await this.startupPromise;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||!IX(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(this.usesCustomDefaultModeInstructions=Q?.collaborationMode?.mode==="default"&&typeof Q.collaborationMode.settings?.developer_instructions==="string",_$(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},hq))?.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=N8(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(M0($,"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:{"tools.experimental_request_user_input.enabled":this.opts.allowUserInput!==!1,"features.default_mode_request_user_input":this.opts.allowUserInput!==!1,...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(" ")+`
83
84
 
84
- `:"";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=new Set,J=null;do{let Q=await this.request("model/list",{cursor:J,limit:100,includeHidden:!1});if(!Array.isArray(Q?.data))throw Error("model/list returned no data array");for(let V of Q.data){if(typeof V?.model!=="string"||!V.model)continue;$.push({id:typeof V.id==="string"&&V.id?V.id:V.model,model:V.model,displayName:typeof V.displayName==="string"&&V.displayName?V.displayName:V.model,description:typeof V.description==="string"?V.description:"",hidden:V.hidden===!0,isDefault:V.isDefault===!0,supportedReasoningEfforts:Cq(V.supportedReasoningEfforts),defaultReasoningEffort:_$(V.defaultReasoningEffort)?V.defaultReasoningEffort:null})}let Y=Q?.nextCursor;if(Y!==null&&typeof Y!=="string")throw Error("model/list returned an invalid nextCursor");if(J=Y||null,J){if(Z.has(J))throw Error("model/list returned a repeated nextCursor");Z.add(J)}}while(J);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(V4("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 X4&&$.method==="turn/start"&&vX($.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 X4&&$.method==="turn/start"&&Z.inputText!==void 0&&(M8($.serverData)||M8({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 z=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let H={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",H)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...z?{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(Nq*2**Math.min(J-1,4),Rq),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 z=this.beginTurnStart(Z);this.startTurn(Z,z).catch((H)=>this.failTurnStart(H,z))},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 z of Q.params?.questions??[]){let H=V[z.question]??V[z.id];if(H!==void 0)X[z.id]={answers:[String(H)]}}this.respond($,{answers:X});return}default:$$("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))})}}});import{createHash as gq}from"node:crypto";class Z${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,z=0)=>{Q.failures=X?0:Q.failures+1;let H=X?N8:Math.min(mq,N8*2**Math.min(Q.failures-1,3));Q.retryAt=this.now()+Math.max(H,Number.isFinite(z)?z:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Q){if(Q.value=X,X.state==="ok")Q.successfulValue=X;else if(X.state==="no_credentials"||X.state==="auth_failed"||l0(X.reason))Q.successfulValue=void 0;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){if(Q.value=void 0,l0(X))Q.successfulValue=void 0;Q.failed=!0,Q.error=X,Y(!1,Number(X?.retryAfterMs))}throw X}).finally(()=>{if(Q.pending===V)Q.pending=void 0});return Q.pending=V,V}readStale($,Z){return this.read($,Z).then((J)=>{if(J.state==="ok")return J;let Q=this.peekSuccessful($);return Q&&(J.state==="network"||J.state==="rate_limited")&&!l0(J.reason)?Q:J}).catch((J)=>{let Q=this.peekSuccessful($);if(Q&&pq(J))return Q;throw J})}peekSuccessful($){return this.entries.get($)?.successfulValue}prime($,Z){this.entries.set($,{value:Z,...Z.state==="ok"?{successfulValue:Z}:{},failed:!1,failures:0,retryAt:this.now()+N8})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function pq($){let Z=$ instanceof Error?$.message:String($);return/abort|timed? ?out|timeout|fetch failed|network|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:408|429|500|502|503|504)\b/i.test(Z)}function l0($){let Z=$ instanceof Error?$.message:String($??"");return/\b(?:401|403)\b|unauthori[sz]ed|authentication (?:failed|required)|not authenticated|not logged in|未登录|not (?:a )?first[- ]party|subscription (?:expired|missing)|(?:invalid|expired|revoked).*(?:key|token)|(?:key|token).*(?:invalid|expired|revoked)|认证(?:失败|失效|不是)|(?:不是|非).*(?:第一方|订阅)/i.test(Z)}function P$($,Z,J){return gq("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function y$($,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 Y2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var N8=60000,mq=300000;var Q1=()=>{};function R8($,Z,J){if(!y.list().some((Y)=>Y.id===$)||y.revision($)!==J)return;let Q=Z?.type==="chatgpt"&&typeof Z.email==="string"?Z.email.trim():"";cX.set($,{revision:J,email:Q||null,...!Q?{error:Z?.type==="chatgpt"?"原生账号未提供邮箱":"该账号未登录 ChatGPT"}:{}})}function lX($){let Z=cX.get($);return Z?.revision===y.revision($)?Z:void 0}var cX;var T8=N(()=>{j0();cX=new Map});import{spawn as cq}from"cross-spawn";import{EventEmitter as lq}from"node:events";import{StringDecoder as uq}from"node:string_decoder";import{createHash as dq}from"node:crypto";function n5($,Z){if(Z.state==="ok"){N1.set($,Z),V2.set($,Z);return}if(Z.state==="no_credentials"||Z.state==="auth_failed")N1.set($,Z),V2.delete($);else if(!V2.has($))N1.set($,Z)}function dX($,Z,J=(Q)=>new N$({accountId:Q})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Q=E8.get($);if(Q)return Q.key===Z?Q.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Y=Promise.resolve().then(async()=>{let V=J($),X,z;try{await V.initialize("lodestar-codex-reset");let H=(await V.request("account/read",{}))?.account;if(!H||H.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");f$($);let G;try{G=await h$(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(j){throw Error(`重置卡请求未确认结果:${j instanceof Error?j.message:String(j)};请用 codex-accounts 核对额度与重置卡次数`,{cause:j})}finally{f$($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(G?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(G)};请用 codex-accounts 核对后再操作`);let W=L$.get($),K;try{K=await S8.read($,async()=>M9(await o5(()=>V.request("account/rateLimits/read",{})),H.planType))}catch(j){K={state:"network",reason:j instanceof Error?j.message:String(j)}}if(L$.get($)!==W)K={state:"auth_failed"};else n5($,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(H){z=H,B(`codex-reset: ${$}: ${H}`)}try{await V.close()}catch(H){let G=`控制连接关闭失败:${H instanceof Error?H.message:String(H)}`;if(B(`codex-reset: ${$}: ${G}`),X)X.cleanupError=G;else throw AggregateError([z,H],`${String(z)};${G}`)}if(!X)throw z;return X}).finally(()=>{if(E8.get($)?.promise===Y)E8.delete($)});return E8.set($,{key:Z,promise:Y}),Y}function iX($,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 iq($){return typeof $==="number"&&Number.isFinite($)&&$>=0&&$<=100?$:null}function x8($){if(!$)return null;return{percent:iq($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function nq($){let Z=x8($?.primary),J=x8($?.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 aq($){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:z}=nq(V);if(!X&&!z)continue;Q.push({limitId:Y,limitName:V?.limitName??null,fiveHour:X,weekly:z,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null,credits:F8(V?.credits)})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function oq($){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 nX($,Z=c){let J=oq($),Q=N1.get(Z),Y=Q?.state==="ok"?Q.buckets??[]:[],V=Y.filter((X)=>uX(X.fiveHour,x8($?.primary))&&uX(X.weekly,x8($?.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 uX($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function sq($){let Z=y.revision($),J=new N$({accountId:$});try{await J.initialize("lodestar-usage");let Y=(await iX(J.request("account/read",{}),i5))?.account;if(R8($,Y,Z),!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let V,X=await o5(()=>{return V=Date.now(),J.request("account/rateLimits/read",{})});return M9(X,Y.planType,V)}catch(Q){if(B(`usage: codex app-server usage failed: ${Q?.message??Q}`),l0(Q))return{state:"auth_failed"};if(Y2(Q))return{state:"rate_limited"};return{state:"network",reason:Q?.message??String(Q)}}finally{await J.close()}}function M9($,Z,J){let{buckets:Q,defaultLimitId:Y}=aq($),V=Q.find((z)=>z.limitId===Y)??Q[0];if(!V)return{state:"network",reason:"empty rate limit response"};let X=Z??$?.rateLimits?.planType??void 0;return V.fiveHour=p5(X,V.fiveHour),{state:"ok",subscriptionType:X,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:dq("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:V.rateLimitReachedType,spendControlReached:V.spendControlReached,credits:V.credits,fiveHour:V.fiveHour,weekly:V.weekly,buckets:Q,defaultLimitId:V.limitId,resetCredits:Number.isInteger($?.rateLimitResetCredits?.availableCount)&&$.rateLimitResetCredits.availableCount>=0?$.rateLimitResetCredits.availableCount:null,...J!==void 0?{readStartedAt:J}:{},fetchedAt:Date.now()}}function X2($=c){return N1.get($)??null}function z2($=c){return V2.get($)??null}function a5($=c){let Z=L$.get($)??0;return{accountId:$,read:()=>(L$.get($)??0)===Z?z2($):null}}function aX($=c){let Z=L$.get($)??0;return S8.read($,async()=>{try{return await sq($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(l0(J))return{state:"auth_failed"};if(Y2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((L$.get($)??0)!==Z)return{state:"auth_failed"};return n5($,J),J})}async function oX($=c){return X2($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}}function sX($,Z=c){let J=L$.get(Z)??0;return S8.read(Z,async()=>{try{let Q,Y=await o5(()=>{return Q=Date.now(),$("account/rateLimits/read",{})}),V=M9(Y,void 0,Q);if(V.state!=="ok")B(`usage: refresh from connection: ${V.state==="network"?V.reason:V.state}`);return V}catch(Q){throw B(`usage: refresh from connection failed: ${Q instanceof Error?Q.message:String(Q)}`),Q}}).then((Q)=>{if((L$.get(Z)??0)!==J)return null;if((L$.get(Z)??0)===J)n5(Z,Q);return Q}).catch((Q)=>{if((L$.get(Z)??0)===J){if(l0(Q))N1.set(Z,{state:"auth_failed"}),V2.delete(Z);else if(!V2.has(Z))N1.set(Z,{state:Y2(Q)?"rate_limited":"network",reason:String(Q)})}return null})}function rX(){return tX}function f$($){tX++,L$.set($,(L$.get($)??0)+1),N1.delete($),V2.delete($),S8.invalidate($)}function o5($){return h$($,"额度查询",{retryRateLimits:!1})}async function h$($,Z="额度查询",J={}){let Q=[1000,4000];for(let Y=0;;Y++)try{return await iX($(),i5)}catch(V){let X=V instanceof Error?V.message:String(V);if(l0(V))throw V;if(Y2(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((H)=>setTimeout(H,Q[Y]))}}var i5=1e4,N1,V2,S8,E8,N$,L$,tX=0;var J$=N(()=>{J1();h();f0();j0();J2();Q1();T8();N1=new Map,V2=new Map,S8=new Z$;E8=new Map;N$=class N$ extends lq{proc;buf="";decoder=new uq("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??c;this.proc=cq($.bin??F9(),["app-server","--listen","stdio://",...$.args??y.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??y.env(Z,{...process.env,...m.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}`))}),O1(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
85
+ `:"";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=new Set,J=null;do{let Q=await this.request("model/list",{cursor:J,limit:100,includeHidden:!1});if(!Array.isArray(Q?.data))throw Error("model/list returned no data array");for(let V of Q.data){if(typeof V?.model!=="string"||!V.model)continue;$.push({id:typeof V.id==="string"&&V.id?V.id:V.model,model:V.model,displayName:typeof V.displayName==="string"&&V.displayName?V.displayName:V.model,description:typeof V.description==="string"?V.description:"",hidden:V.hidden===!0,isDefault:V.isDefault===!0,supportedReasoningEfforts:uq(V.supportedReasoningEfforts),defaultReasoningEffort:_$(V.defaultReasoningEffort)?V.defaultReasoningEffort:null})}let Y=Q?.nextCursor;if(Y!==null&&typeof Y!=="string")throw Error("model/list returned an invalid nextCursor");if(J=Y||null,J){if(Z.has(J))throw Error("model/list returned a repeated nextCursor");Z.add(J)}}while(J);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(V4("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 X4&&$.method==="turn/start"&&pX($.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 X4&&$.method==="turn/start"&&Z.inputText!==void 0&&(O8($.serverData)||O8({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 z=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let H={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",H)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...z?{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=this.opts.allowUserInput===!1||this.usesCustomDefaultModeInstructions&&!!this.opts.appendSystemPrompt,Y=this.opts.model??this.lastModel;if(Q&&!Y)throw Error("Codex model is missing while applying the current invocation policy");let V=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"},...Q?{collaborationMode:{mode:"default",settings:{model:Y,reasoning_effort:this.opts.effort??this.lastEffort??null,developer_instructions:this.opts.appendSystemPrompt??null}}}:{}});this.recordTurnStarted(V?.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(Iq*2**Math.min(J-1,4),gq),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 z=this.beginTurnStart(Z);this.startTurn(Z,z).catch((H)=>this.failTurnStart(H,z))},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 z of Q.params?.questions??[]){let H=V[z.question]??V[z.id];if(H!==void 0)X[z.id]={answers:[String(H)]}}this.respond($,{answers:X});return}default:$$("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.inputPolicyAbort?.abort(Error("Codex process cancelled")),this.startupPromise){this.expectedExit=!0;let Y;try{await Promise.race([this.startupPromise.catch(()=>{}),new Promise((V,X)=>{Y=setTimeout(()=>X(Error(`Codex model catalog preparation did not exit within ${$*2}ms`)),$*2)})])}finally{if(Y)clearTimeout(Y)}}if(!this.alive){if(await this.waitForExit($)){await this.disposeInputPolicy();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($)){await this.disposeInputPolicy();return}if(B(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($)){await this.disposeInputPolicy();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}async disposeInputPolicy(){if(!this.inputPolicyCatalog)return;await this.inputPolicyCatalog.dispose(),this.inputPolicyCatalog=null}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))})}}});import{createHash as eq}from"node:crypto";class Z${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,z=0)=>{Q.failures=X?0:Q.failures+1;let H=X?R8:Math.min($D,R8*2**Math.min(Q.failures-1,3));Q.retryAt=this.now()+Math.max(H,Number.isFinite(z)?z:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Q){if(Q.value=X,X.state==="ok")Q.successfulValue=X;else if(X.state==="no_credentials"||X.state==="auth_failed"||l0(X.reason))Q.successfulValue=void 0;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){if(Q.value=void 0,l0(X))Q.successfulValue=void 0;Q.failed=!0,Q.error=X,Y(!1,Number(X?.retryAfterMs))}throw X}).finally(()=>{if(Q.pending===V)Q.pending=void 0});return Q.pending=V,V}readStale($,Z){return this.read($,Z).then((J)=>{if(J.state==="ok")return J;let Q=this.peekSuccessful($);return Q&&(J.state==="network"||J.state==="rate_limited")&&!l0(J.reason)?Q:J}).catch((J)=>{let Q=this.peekSuccessful($);if(Q&&ZD(J))return Q;throw J})}peekSuccessful($){return this.entries.get($)?.successfulValue}prime($,Z){this.entries.set($,{value:Z,...Z.state==="ok"?{successfulValue:Z}:{},failed:!1,failures:0,retryAt:this.now()+R8})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function ZD($){let Z=$ instanceof Error?$.message:String($);return/abort|timed? ?out|timeout|fetch failed|network|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:408|429|500|502|503|504)\b/i.test(Z)}function l0($){let Z=$ instanceof Error?$.message:String($??"");return/\b(?:401|403)\b|unauthori[sz]ed|authentication (?:failed|required)|not authenticated|not logged in|未登录|not (?:a )?first[- ]party|subscription (?:expired|missing)|(?:invalid|expired|revoked).*(?:key|token)|(?:key|token).*(?:invalid|expired|revoked)|认证(?:失败|失效|不是)|(?:不是|非).*(?:第一方|订阅)/i.test(Z)}function L$($,Z,J){return eq("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function y$($,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 V2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var R8=60000,$D=300000;var Q1=()=>{};function T8($,Z,J){if(!v.list().some((Y)=>Y.id===$)||v.revision($)!==J)return;let Q=Z?.type==="chatgpt"&&typeof Z.email==="string"?Z.email.trim():"";oX.set($,{revision:J,email:Q||null,...!Q?{error:Z?.type==="chatgpt"?"原生账号未提供邮箱":"该账号未登录 ChatGPT"}:{}})}function sX($){let Z=oX.get($);return Z?.revision===v.revision($)?Z:void 0}var oX;var E8=R(()=>{j0();oX=new Map});import{spawn as JD}from"cross-spawn";import{EventEmitter as QD}from"node:events";import{StringDecoder as YD}from"node:string_decoder";import{createHash as VD}from"node:crypto";function a5($,Z){if(Z.state==="ok"){N1.set($,Z),X2.set($,Z);return}if(Z.state==="no_credentials"||Z.state==="auth_failed")N1.set($,Z),X2.delete($);else if(!X2.has($))N1.set($,Z)}function rX($,Z,J=(Q)=>new N$({accountId:Q})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Q=x8.get($);if(Q)return Q.key===Z?Q.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Y=Promise.resolve().then(async()=>{let V=J($),X,z;try{await V.initialize("lodestar-codex-reset");let H=(await V.request("account/read",{}))?.account;if(!H||H.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");f$($);let G;try{G=await h$(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(j){throw Error(`重置卡请求未确认结果:${j instanceof Error?j.message:String(j)};请用 codex-accounts 核对额度与重置卡次数`,{cause:j})}finally{f$($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(G?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(G)};请用 codex-accounts 核对后再操作`);let W=P$.get($),K;try{K=await C8.read($,async()=>O9(await s5(()=>V.request("account/rateLimits/read",{})),H.planType))}catch(j){K={state:"network",reason:j instanceof Error?j.message:String(j)}}if(P$.get($)!==W)K={state:"auth_failed"};else a5($,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(H){z=H,B(`codex-reset: ${$}: ${H}`)}try{await V.close()}catch(H){let G=`控制连接关闭失败:${H instanceof Error?H.message:String(H)}`;if(B(`codex-reset: ${$}: ${G}`),X)X.cleanupError=G;else throw AggregateError([z,H],`${String(z)};${G}`)}if(!X)throw z;return X}).finally(()=>{if(x8.get($)?.promise===Y)x8.delete($)});return x8.set($,{key:Z,promise:Y}),Y}function eX($,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 XD($){return typeof $==="number"&&Number.isFinite($)&&$>=0&&$<=100?$:null}function S8($){if(!$)return null;return{percent:XD($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function zD($){let Z=S8($?.primary),J=S8($?.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 HD($){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:z}=zD(V);if(!X&&!z)continue;Q.push({limitId:Y,limitName:V?.limitName??null,fiveHour:X,weekly:z,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null,credits:U8(V?.credits)})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function GD($){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 $z($,Z=l){let J=GD($),Q=N1.get(Z),Y=Q?.state==="ok"?Q.buckets??[]:[],V=Y.filter((X)=>tX(X.fiveHour,S8($?.primary))&&tX(X.weekly,S8($?.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 tX($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function WD($){let Z=v.revision($),J=new N$({accountId:$});try{await J.initialize("lodestar-usage");let Y=(await eX(J.request("account/read",{}),n5))?.account;if(T8($,Y,Z),!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let V,X=await s5(()=>{return V=Date.now(),J.request("account/rateLimits/read",{})});return O9(X,Y.planType,V)}catch(Q){if(B(`usage: codex app-server usage failed: ${Q?.message??Q}`),l0(Q))return{state:"auth_failed"};if(V2(Q))return{state:"rate_limited"};return{state:"network",reason:Q?.message??String(Q)}}finally{await J.close()}}function O9($,Z,J){let{buckets:Q,defaultLimitId:Y}=HD($),V=Q.find((z)=>z.limitId===Y)??Q[0];if(!V)return{state:"network",reason:"empty rate limit response"};let X=Z??$?.rateLimits?.planType??void 0;return V.fiveHour=c5(X,V.fiveHour),{state:"ok",subscriptionType:X,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:VD("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:V.rateLimitReachedType,spendControlReached:V.spendControlReached,credits:V.credits,fiveHour:V.fiveHour,weekly:V.weekly,buckets:Q,defaultLimitId:V.limitId,resetCredits:Number.isInteger($?.rateLimitResetCredits?.availableCount)&&$.rateLimitResetCredits.availableCount>=0?$.rateLimitResetCredits.availableCount:null,...J!==void 0?{readStartedAt:J}:{},fetchedAt:Date.now()}}function z2($=l){return N1.get($)??null}function H2($=l){return X2.get($)??null}function o5($=l){let Z=P$.get($)??0;return{accountId:$,read:()=>(P$.get($)??0)===Z?H2($):null}}function Zz($=l){let Z=P$.get($)??0;return C8.read($,async()=>{try{return await WD($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(l0(J))return{state:"auth_failed"};if(V2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((P$.get($)??0)!==Z)return{state:"auth_failed"};return a5($,J),J})}async function Jz($=l){return z2($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}}function Qz($,Z=l){let J=P$.get(Z)??0;return C8.read(Z,async()=>{try{let Q,Y=await s5(()=>{return Q=Date.now(),$("account/rateLimits/read",{})}),V=O9(Y,void 0,Q);if(V.state!=="ok")B(`usage: refresh from connection: ${V.state==="network"?V.reason:V.state}`);return V}catch(Q){throw B(`usage: refresh from connection failed: ${Q instanceof Error?Q.message:String(Q)}`),Q}}).then((Q)=>{if((P$.get(Z)??0)!==J)return null;if((P$.get(Z)??0)===J)a5(Z,Q);return Q}).catch((Q)=>{if((P$.get(Z)??0)===J){if(l0(Q))N1.set(Z,{state:"auth_failed"}),X2.delete(Z);else if(!X2.has(Z))N1.set(Z,{state:V2(Q)?"rate_limited":"network",reason:String(Q)})}return null})}function Vz(){return Yz}function f$($){Yz++,P$.set($,(P$.get($)??0)+1),N1.delete($),X2.delete($),C8.invalidate($)}function s5($){return h$($,"额度查询",{retryRateLimits:!1})}async function h$($,Z="额度查询",J={}){let Q=[1000,4000];for(let Y=0;;Y++)try{return await eX($(),n5)}catch(V){let X=V instanceof Error?V.message:String(V);if(l0(V))throw V;if(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(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((H)=>setTimeout(H,Q[Y]))}}var n5=1e4,N1,X2,C8,x8,N$,P$,Yz=0;var J$=R(()=>{J1();h();f0();j0();Q2();Q1();E8();N1=new Map,X2=new Map,C8=new Z$;x8=new Map;N$=class N$ extends QD{proc;buf="";decoder=new YD("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??l;this.proc=JD($.bin??U9(),["app-server","--listen","stdio://",...$.args??v.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??v.env(Z,{...process.env,...m.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}`))}),O1(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
85
86
  `))>=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}`}})+`
86
87
  `);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"})+`
87
- `,(Q)=>Q?J(Q):Z())})}isAlive(){return this.alive}request($,Z,J=i5){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})+`
88
- `,(z)=>{if(!z)return;let H=this.pending.get(Q);if(!H)return;this.pending.delete(Q),clearTimeout(H.timer),H.reject(Error(`codex app-server write failed for ${$}: ${z.message}`))})}catch(z){this.pending.delete(Q),clearTimeout(X),V(z instanceof Error?z:Error(String(z)))}})}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)}}};L$=new Map});var Qz={};r$(Qz,{waitForTokenSourceModelRefresh:()=>rq,tokenSourceRuntimeModels:()=>R1,tokenSourceRuntimeModel:()=>I$,tokenSourceRegistryRevision:()=>t5,tokenSourceProcessRevision:()=>G4,tokenSourceFactories:()=>H2,setDefaultTokenSource:()=>$Z,scrubDshEnv:()=>O9,scrubAnthropicEnv:()=>u0,resetTokenSourceRegistry:()=>ZZ,registerTokenSourceFactory:()=>D0,registerTokenSource:()=>r5,refreshAllTokenSourceModels:()=>tq,pendingTokenSourceModelRefresh:()=>Jz,listTokenSourcesByAgent:()=>$z,listTokenSources:()=>d0,listTokenSourceAccounts:()=>Zz,listEnabledTokenSourcesByAgent:()=>e5,getTokenSourceForAccount:()=>G0,getTokenSource:()=>C0,ANTHROPIC_ENV_KEYS:()=>b8});function u0($){let Z={...$};for(let J of b8)delete Z[J];return delete Z.LODESTAR_PACKY_API_KEY,Z}function O9($){let Z=u0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function R1($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function I$($,Z){let J=(Q)=>$.agent==="claude"?Q?.replace(/\[1m\]$/,""):Q;return R1($).find((Q)=>J(Q.model)===J(Z))}function G4($,Z){let J=$?.spawnRevision??null,Q=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Q===void 0?J:JSON.stringify([J,Q])}function D0($){eX.set($.kind,$)}function H2(){return[...eX.values()]}function t5(){return s5}function r5($,Z){if(A9.set($.id,$),Z?.default||C8===null)C8=$.id}function C0($){return $?A9.get($):void 0}function G0($,Z="default"){let J=C0($);return J?.forAccount?J.forAccount(Z):J}function d0(){return[...A9.values()]}function $z($){return d0().filter((Z)=>Z.agent===$)}function e5($){return $z($).filter((Z)=>Z.enabled)}function $Z($){if(A9.has($))C8=$}function ZZ(){A9.clear(),C8=null,s5++}function tq(){let $=s5;if(H4?.generation===$)return H4.promise;let Z=Promise.allSettled(Zz().map(async(J)=>{await J.refreshModels(),B(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(H4?.promise===Z)H4=null});return H4={generation:$,promise:Z},Z}function Zz(){return d0().flatMap(($)=>$.forAccount?y.list().map((Z)=>$.forAccount(Z.id)):[$])}function Jz(){return H4?.promise??null}async function rq(){let $;while($=Jz())await $}var b8,eX,A9,C8=null,s5=0,H4=null;var X0=N(()=>{h();j0();b8=["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"];eX=new Map;A9=new Map});import{existsSync as eq,readFileSync as $D}from"node:fs";class Yz{deps;lastUses=new Map;constructor($){this.deps=$}recordUsage($,Z,J){let Q=J??this.deps.cachedUsage($);if(Q?.state!=="ok")return;let Y=Q.accountFingerprint??this.deps.identity($);if(!Y)return;this.lastUses.set(JSON.stringify([Y,Z2(Q,Z)]),this.deps.now())}weekWasUsed($,Z,J){let Q=this.lastUses.get(JSON.stringify([$,Z2(Z,J)]));return Q!==void 0&&SX(Z,J,Q)}blocks(){if(!eq(this.deps.stateFile))return[];let $=JSON.parse($D(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.credits!=null&&(!F8(Z.credits)||Z.credits.balance!==null&&!Number.isFinite(Z.credits.balance))||Z.creditsObservedAt!==void 0&&!Number.isFinite(Z.creditsObservedAt)||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"?$2($.usage,Z):null,Q=["fiveHour","weekly"].flatMap((z)=>{let H=J?.[z];return H?[{kind:z,percent:H.percent,reset:H.resetsAt?.getTime()??null}]:[]}),Y=Z2($.usage,Z),V=JSON.stringify([$.identity,Y]),X=this.blocks().filter((z)=>z.key!==V);X.push({key:V,identity:$.identity,meter:Y,windows:Q,credits:J?.credits??null,blockedAt:this.deps.now()}),a(this.deps.stateFile,{version:1,blocks:X})}async choose($){$.signal?.throwIfAborted();let Z=this.deps.accounts();if($.preferred){let Q=Z.find((Y)=>Y.id===$.preferred);if(!Q)throw Error(`指定 Codex 账号不存在:${$.preferred}`);return{selected:{account:Q,identity:`record:${Q.id}`,usage:null,state:"manual",score:null,shares:null,remaining:null,hours:null},candidates:[]}}let J=new Map;if($.preferCachedUsage){let Q=await this.chooseAutomatic(Z,$,!0,J);if(Q.selected)return Q}return this.chooseAutomatic(Z,$,!1,J)}async chooseAutomatic($,Z,J,Q){Z.signal?.throwIfAborted();let Y=await Promise.all($.map(async(P)=>{let F,U=null,A=`record:${P.id}`;if(this.deps.pendingLogin(P.id))F={state:"network",reason:"正在登录"};else try{F=J?this.deps.cachedUsage(P.id):await this.deps.usage(P.id);let M=F?.state==="ok"?F.accountFingerprint??this.deps.identity(P.id):null;if(M)A=M;else if(F?.state==="ok")U="账号身份 MISS";if(F?.state==="ok"&&!U){let O=Q.get(P.id);if(!O)O=this.deps.compatible(P.id,Z.model,Z.effort),Q.set(P.id,O);U=await O}}catch(M){F={state:"network",reason:String(M)}}return{account:P,usage:F,identity:A,reason:U}}));Z.signal?.throwIfAborted();let V=Z.failedAccountId&&Y.find((P)=>P.account.id===Z.failedAccountId);if(V&&V.usage?.state==="ok")this.block({account:V.account,usage:V.usage,identity:V.identity,...D9(V.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let X=this.blocks(),z=this.deps.now(),H=new Set,G=new Map,W=new Map,K=Y.map(({account:P,usage:F,identity:U,reason:A})=>{let M=D9(F??{state:"network",reason:"尚无额度缓存"},Z.model,z,Z.effort);if(A)M={...M,state:"miss",score:null,reason:A};let O=W.get(U);if(W.set(U,O??P.name),O)M={...M,state:"miss",score:null,reason:`重复账号:${O}`};let R=F?.state==="ok"?Z2(F,Z.model):null,w=X.find((T)=>(T.identity===U||T.identity===`record:${P.id}`)&&T.meter===R);if(w&&F?.state==="ok"&&!O){let T=$2(F,Z.model),f=F.readStartedAt??F.fetchedAt,u=f>(w.blockedAt??0),C=u&&f>(w.creditsObservedAt??0),g=C&&TX(w.credits,T.credits),Y0=u&&M.funding!=="credits"&&w.windows.some((e)=>{let E=T[e.kind];return E&&E.percent!==null&&(e.percent!==null&&E.percent<e.percent||e.reset!==null&&e.reset<=z&&(E.resetsAt?.getTime()??0)>e.reset)});if(M.state==="ready")if(Y0||g)H.add(w.key);else M={...M,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"};if(!H.has(w.key)&&C&&!g&&T.credits!=null)G.set(w.key,{...w,credits:T.credits,creditsObservedAt:f})}return{account:P,usage:F,identity:U,...M,...O?{duplicateOf:O}:{}}});if(H.size||G.size)a(this.deps.stateFile,{version:1,blocks:X.filter((P)=>!H.has(P.key)).map((P)=>G.get(P.key)??P)});let j=K.filter((P)=>P.state==="ready");j.sort(U8);let _=j[0]??null,D=K.filter((P)=>P.state==="exhausted"||P.state==="waiting"),L=D.length?Math.min(...D.map((P)=>P.retryAt??z+60000)):void 0;for(let P of K)B(`codex scheduler${J?" [cache]":""}: ${P.account.name} ${P.state} priority=${P.funding??P.priority??"score"} score=${P.score??(P.funding==="credits"||P.priority==="expiring"?"N/A":"MISS")}${P.reason?` (${P.reason})`:""}`);return{selected:_,candidates:K,...L!==void 0?{retryAt:L}:{}}}}function ZD($,Z,J){let Q=I$($,Z);if(!Q)return`模型目录缺少 ${Z}`;if(Q.unavailableReason)return`${Z} 不可用:${Q.unavailableReason}`;if(J&&!Q.efforts.includes(J))return`${Z} 缺少推理档位 ${J}(目录档位:${Q.efforts.join("、")||"MISS"})`;return null}async function JD($,Z,J,Q=Date.now()){if(!$.enabled||$.modelCatalogState?.status!=="ready")return`模型目录查询失败:${$.modelCatalogState?.error??($.enabled?"模型目录 MISS":"订阅来源未启用")}`;return ZD($,Z,J)}var G2;var k8=N(()=>{j0();J$();J2();X0();H0();x0();h();G2=new Yz({accounts:()=>y.list(),usage:async($)=>X2($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"},cachedUsage:z2,identity:($)=>y.fingerprint($),pendingLogin:M1,now:Date.now,stateFile:PV,compatible:async($,Z,J)=>{let Q=G0("codex-sub",$);if(!Q)return"订阅来源 MISS";return JD(Q,Z,J)}})});import{createHash as QD}from"node:crypto";import{readFile as YD}from"node:fs/promises";import{join as VD}from"node:path";function Vz($){if(!$?.enabled||$.kind!=="codex-subscription"||$.modelCatalogState?.status!=="ready")throw Error(`后台激活模型目录 MISS:${$?.modelCatalogState?.error??"订阅目录未就绪"}`);let Z=($.modelSelection?.availableModels??$.models).find((Q)=>Q.model===Y1&&Q.origin!=="custom");if(!Z||Z.unavailableReason)throw Error(`后台激活需要 ${Y1}:${Z?.unavailableReason??"原生目录未提供"}`);let J=Q2.find((Q)=>Z.efforts.includes(Q));if(!J)throw Error(`${Y1} 推理档位 MISS`);return J}function XD($){return{model:Y1,instructions:"",store:!1,stream:!0,input:[{role:"user",content:[{type:"input_text",text:"你好,只回复“你好”。"}]}],tools:[],tool_choice:"none",parallel_tool_calls:!1,reasoning:{effort:$},text:{verbosity:"low"},service_tier:"default"}}function JZ($){let Z=D9($,"");return!!$.defaultLimitId&&($.fiveHour===null||$.fiveHour.percent===0)&&xX($,"")&&Z.state==="ready"&&Z.funding!=="credits"}async function zD($){let Z;try{Z=await YD(VD(y.home($),"auth.json"),"utf8")}catch(Q){throw Error(`后台激活无法读取原生 auth.json:${Q.code??"读取失败"}`)}let J;try{J=JSON.parse(Z)}catch{throw Error("后台激活的原生 auth.json 不是有效 JSON")}if(J?.auth_mode!=="chatgpt"||typeof J.tokens?.access_token!=="string"||!J.tokens.access_token||typeof J.tokens.account_id!=="string"||!J.tokens.account_id)throw Error("后台激活的原生 ChatGPT 文件登录态无效");return{accessToken:J.tokens.access_token,accountId:J.tokens.account_id}}function HD($){if(typeof $!=="string"||!$)throw Error("原生 chatgpt_base_url MISS");let Z=new URL($);if(!["http:","https:"].includes(Z.protocol)||Z.username||Z.password||Z.search||Z.hash)throw Error("原生 chatgpt_base_url 格式无效");let J=Z.pathname.replace(/\/+$/,"");return Z.pathname=J.endsWith("/codex/responses")?J:J.endsWith("/codex")?`${J}/responses`:`${J}/codex/responses`,Z.href}async function GD($,Z){if(!$.ok)throw Error(`后台激活 HTTP ${$.status}:${await $.text()}`);if(!$.body)throw Error("后台激活响应缺少事件流");let J=$.body.getReader(),Q=new TextDecoder,Y="",V="",X,z=()=>{let H=V;if(V="",!H||H.trim()==="[DONE]")return;let G;try{G=JSON.parse(H)}catch{throw Error("后台激活返回无效 JSON 事件")}if(G.type==="error"||["response.failed","response.incomplete"].includes(G.type))throw Error(`后台激活失败:${G.error?.message??G.response?.error?.message??G.message??G.type}`);if(!["response.completed","response.done"].includes(G.type))return;if(G.response?.status!=="completed")throw Error(`后台激活终态异常:${G.response?.status??"MISS"}`);let W=G.response?.usage?.total_tokens;if(!Number.isFinite(W)||W<=0)throw Error("后台激活已结束,但真实 token 用量 MISS");return W};try{while(!0){let{value:H,done:G}=await J.read();if(Y+=G?Q.decode():Q.decode(H,{stream:!0}),Y.length+V.length>1e6)throw Error("后台激活响应事件超过大小限制");let W;while((W=Y.indexOf(`
88
+ `,(Q)=>Q?J(Q):Z())})}isAlive(){return this.alive}request($,Z,J=n5){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})+`
89
+ `,(z)=>{if(!z)return;let H=this.pending.get(Q);if(!H)return;this.pending.delete(Q),clearTimeout(H.timer),H.reject(Error(`codex app-server write failed for ${$}: ${z.message}`))})}catch(z){this.pending.delete(Q),clearTimeout(X),V(z instanceof Error?z:Error(String(z)))}})}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)}}};P$=new Map});var Wz={};r$(Wz,{waitForTokenSourceModelRefresh:()=>BD,tokenSourceRuntimeModels:()=>R1,tokenSourceRuntimeModel:()=>I$,tokenSourceRegistryRevision:()=>r5,tokenSourceProcessRevision:()=>G4,tokenSourceFactories:()=>G2,setDefaultTokenSource:()=>ZZ,scrubDshEnv:()=>A9,scrubAnthropicEnv:()=>u0,resetTokenSourceRegistry:()=>JZ,registerTokenSourceFactory:()=>D0,registerTokenSource:()=>e5,refreshAllTokenSourceModels:()=>KD,pendingTokenSourceModelRefresh:()=>Gz,listTokenSourcesByAgent:()=>zz,listTokenSources:()=>d0,listTokenSourceAccounts:()=>Hz,listEnabledTokenSourcesByAgent:()=>$Z,getTokenSourceForAccount:()=>G0,getTokenSource:()=>C0,ANTHROPIC_ENV_KEYS:()=>k8});function u0($){let Z={...$};for(let J of k8)delete Z[J];return delete Z.LODESTAR_PACKY_API_KEY,Z}function A9($){let Z=u0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function R1($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function I$($,Z){let J=(Q)=>$.agent==="claude"?Q?.replace(/\[1m\]$/,""):Q;return R1($).find((Q)=>J(Q.model)===J(Z))}function G4($,Z){let J=$?.spawnRevision??null,Q=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Q===void 0?J:JSON.stringify([J,Q])}function D0($){Xz.set($.kind,$)}function G2(){return[...Xz.values()]}function r5(){return t5}function e5($,Z){if(N9.set($.id,$),Z?.default||b8===null)b8=$.id}function C0($){return $?N9.get($):void 0}function G0($,Z="default"){let J=C0($);return J?.forAccount?J.forAccount(Z):J}function d0(){return[...N9.values()]}function zz($){return d0().filter((Z)=>Z.agent===$)}function $Z($){return zz($).filter((Z)=>Z.enabled)}function ZZ($){if(N9.has($))b8=$}function JZ(){N9.clear(),b8=null,t5++}function KD(){let $=t5;if(H4?.generation===$)return H4.promise;let Z=Promise.allSettled(Hz().map(async(J)=>{await J.refreshModels(),B(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(H4?.promise===Z)H4=null});return H4={generation:$,promise:Z},Z}function Hz(){return d0().flatMap(($)=>$.forAccount?v.list().map((Z)=>$.forAccount(Z.id)):[$])}function Gz(){return H4?.promise??null}async function BD(){let $;while($=Gz())await $}var k8,Xz,N9,b8=null,t5=0,H4=null;var z0=R(()=>{h();j0();k8=["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"];Xz=new Map;N9=new Map});import{existsSync as jD,readFileSync as _D}from"node:fs";class Kz{deps;lastUses=new Map;constructor($){this.deps=$}recordUsage($,Z,J){let Q=J??this.deps.cachedUsage($);if(Q?.state!=="ok")return;let Y=Q.accountFingerprint??this.deps.identity($);if(!Y)return;this.lastUses.set(JSON.stringify([Y,J2(Q,Z)]),this.deps.now())}weekWasUsed($,Z,J){let Q=this.lastUses.get(JSON.stringify([$,J2(Z,J)]));return Q!==void 0&&fX(Z,J,Q)}blocks(){if(!jD(this.deps.stateFile))return[];let $=JSON.parse(_D(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.credits!=null&&(!U8(Z.credits)||Z.credits.balance!==null&&!Number.isFinite(Z.credits.balance))||Z.creditsObservedAt!==void 0&&!Number.isFinite(Z.creditsObservedAt)||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"?Z2($.usage,Z):null,Q=["fiveHour","weekly"].flatMap((z)=>{let H=J?.[z];return H?[{kind:z,percent:H.percent,reset:H.resetsAt?.getTime()??null}]:[]}),Y=J2($.usage,Z),V=JSON.stringify([$.identity,Y]),X=this.blocks().filter((z)=>z.key!==V);X.push({key:V,identity:$.identity,meter:Y,windows:Q,credits:J?.credits??null,blockedAt:this.deps.now()}),a(this.deps.stateFile,{version:1,blocks:X})}async choose($){$.signal?.throwIfAborted();let Z=this.deps.accounts();if($.preferred){let Q=Z.find((Y)=>Y.id===$.preferred);if(!Q)throw Error(`指定 Codex 账号不存在:${$.preferred}`);return{selected:{account:Q,identity:`record:${Q.id}`,usage:null,state:"manual",score:null,shares:null,remaining:null,hours:null},candidates:[]}}let J=new Map;if($.preferCachedUsage){let Q=await this.chooseAutomatic(Z,$,!0,J);if(Q.selected)return Q}return this.chooseAutomatic(Z,$,!1,J)}async chooseAutomatic($,Z,J,Q){Z.signal?.throwIfAborted();let Y=await Promise.all($.map(async(L)=>{let F,U=null,A=`record:${L.id}`;if(this.deps.pendingLogin(L.id))F={state:"network",reason:"正在登录"};else try{F=J?this.deps.cachedUsage(L.id):await this.deps.usage(L.id);let M=F?.state==="ok"?F.accountFingerprint??this.deps.identity(L.id):null;if(M)A=M;else if(F?.state==="ok")U="账号身份 MISS";if(F?.state==="ok"&&!U){let O=Q.get(L.id);if(!O)O=this.deps.compatible(L.id,Z.model,Z.effort),Q.set(L.id,O);U=await O}}catch(M){F={state:"network",reason:String(M)}}return{account:L,usage:F,identity:A,reason:U}}));Z.signal?.throwIfAborted();let V=Z.failedAccountId&&Y.find((L)=>L.account.id===Z.failedAccountId);if(V&&V.usage?.state==="ok")this.block({account:V.account,usage:V.usage,identity:V.identity,...F9(V.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let X=this.blocks(),z=this.deps.now(),H=new Set,G=new Map,W=new Map,K=Y.map(({account:L,usage:F,identity:U,reason:A})=>{let M=F9(F??{state:"network",reason:"尚无额度缓存"},Z.model,z,Z.effort);if(A)M={...M,state:"miss",score:null,reason:A};let O=W.get(U);if(W.set(U,O??L.name),O)M={...M,state:"miss",score:null,reason:`重复账号:${O}`};let T=F?.state==="ok"?J2(F,Z.model):null,k=X.find((E)=>(E.identity===U||E.identity===`record:${L.id}`)&&E.meter===T);if(k&&F?.state==="ok"&&!O){let E=Z2(F,Z.model),f=F.readStartedAt??F.fetchedAt,d=f>(k.blockedAt??0),S=d&&f>(k.creditsObservedAt??0),g=S&&wX(k.credits,E.credits),V0=d&&M.funding!=="credits"&&k.windows.some((e)=>{let c=E[e.kind];return c&&c.percent!==null&&(e.percent!==null&&c.percent<e.percent||e.reset!==null&&e.reset<=z&&(c.resetsAt?.getTime()??0)>e.reset)});if(M.state==="ready")if(V0||g)H.add(k.key);else M={...M,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"};if(!H.has(k.key)&&S&&!g&&E.credits!=null)G.set(k.key,{...k,credits:E.credits,creditsObservedAt:f})}return{account:L,usage:F,identity:U,...M,...O?{duplicateOf:O}:{}}});if(H.size||G.size)a(this.deps.stateFile,{version:1,blocks:X.filter((L)=>!H.has(L.key)).map((L)=>G.get(L.key)??L)});let j=K.filter((L)=>L.state==="ready");j.sort(M8);let _=j[0]??null,D=K.filter((L)=>L.state==="exhausted"||L.state==="waiting"),P=D.length?Math.min(...D.map((L)=>L.retryAt??z+60000)):void 0;for(let L of K)B(`codex scheduler${J?" [cache]":""}: ${L.account.name} ${L.state} priority=${L.funding??L.priority??"score"} score=${L.score??(L.funding==="credits"||L.priority==="expiring"?"N/A":"MISS")}${L.reason?` (${L.reason})`:""}`);return{selected:_,candidates:K,...P!==void 0?{retryAt:P}:{}}}}function LD($,Z,J){let Q=I$($,Z);if(!Q)return`模型目录缺少 ${Z}`;if(Q.unavailableReason)return`${Z} 不可用:${Q.unavailableReason}`;if(J&&!Q.efforts.includes(J))return`${Z} 缺少推理档位 ${J}(目录档位:${Q.efforts.join("、")||"MISS"})`;return null}async function PD($,Z,J,Q=Date.now()){if(!$.enabled||$.modelCatalogState?.status!=="ready")return`模型目录查询失败:${$.modelCatalogState?.error??($.enabled?"模型目录 MISS":"订阅来源未启用")}`;return LD($,Z,J)}var W2;var w8=R(()=>{j0();J$();Q2();z0();H0();x0();h();W2=new Kz({accounts:()=>v.list(),usage:async($)=>z2($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"},cachedUsage:H2,identity:($)=>v.fingerprint($),pendingLogin:M1,now:Date.now,stateFile:qV,compatible:async($,Z,J)=>{let Q=G0("codex-sub",$);if(!Q)return"订阅来源 MISS";return PD(Q,Z,J)}})});import{createHash as qD}from"node:crypto";import{readFile as DD}from"node:fs/promises";import{join as FD}from"node:path";function Bz($){if(!$?.enabled||$.kind!=="codex-subscription"||$.modelCatalogState?.status!=="ready")throw Error(`后台激活模型目录 MISS:${$?.modelCatalogState?.error??"订阅目录未就绪"}`);let Z=($.modelSelection?.availableModels??$.models).find((Q)=>Q.model===Y1&&Q.origin!=="custom");if(!Z||Z.unavailableReason)throw Error(`后台激活需要 ${Y1}:${Z?.unavailableReason??"原生目录未提供"}`);let J=Y2.find((Q)=>Z.efforts.includes(Q));if(!J)throw Error(`${Y1} 推理档位 MISS`);return J}function UD($){return{model:Y1,instructions:"",store:!1,stream:!0,input:[{role:"user",content:[{type:"input_text",text:"你好,只回复“你好”。"}]}],tools:[],tool_choice:"none",parallel_tool_calls:!1,reasoning:{effort:$},text:{verbosity:"low"},service_tier:"default"}}function QZ($){let Z=F9($,"");return!!$.defaultLimitId&&($.fiveHour===null||$.fiveHour.percent===0)&&yX($,"")&&Z.state==="ready"&&Z.funding!=="credits"}async function MD($){let Z;try{Z=await DD(FD(v.home($),"auth.json"),"utf8")}catch(Q){throw Error(`后台激活无法读取原生 auth.json:${Q.code??"读取失败"}`)}let J;try{J=JSON.parse(Z)}catch{throw Error("后台激活的原生 auth.json 不是有效 JSON")}if(J?.auth_mode!=="chatgpt"||typeof J.tokens?.access_token!=="string"||!J.tokens.access_token||typeof J.tokens.account_id!=="string"||!J.tokens.account_id)throw Error("后台激活的原生 ChatGPT 文件登录态无效");return{accessToken:J.tokens.access_token,accountId:J.tokens.account_id}}function OD($){if(typeof $!=="string"||!$)throw Error("原生 chatgpt_base_url MISS");let Z=new URL($);if(!["http:","https:"].includes(Z.protocol)||Z.username||Z.password||Z.search||Z.hash)throw Error("原生 chatgpt_base_url 格式无效");let J=Z.pathname.replace(/\/+$/,"");return Z.pathname=J.endsWith("/codex/responses")?J:J.endsWith("/codex")?`${J}/responses`:`${J}/codex/responses`,Z.href}async function AD($,Z){if(!$.ok)throw Error(`后台激活 HTTP ${$.status}:${await $.text()}`);if(!$.body)throw Error("后台激活响应缺少事件流");let J=$.body.getReader(),Q=new TextDecoder,Y="",V="",X,z=()=>{let H=V;if(V="",!H||H.trim()==="[DONE]")return;let G;try{G=JSON.parse(H)}catch{throw Error("后台激活返回无效 JSON 事件")}if(G.type==="error"||["response.failed","response.incomplete"].includes(G.type))throw Error(`后台激活失败:${G.error?.message??G.response?.error?.message??G.message??G.type}`);if(!["response.completed","response.done"].includes(G.type))return;if(G.response?.status!=="completed")throw Error(`后台激活终态异常:${G.response?.status??"MISS"}`);let W=G.response?.usage?.total_tokens;if(!Number.isFinite(W)||W<=0)throw Error("后台激活已结束,但真实 token 用量 MISS");return W};try{while(!0){let{value:H,done:G}=await J.read();if(Y+=G?Q.decode():Q.decode(H,{stream:!0}),Y.length+V.length>1e6)throw Error("后台激活响应事件超过大小限制");let W;while((W=Y.indexOf(`
89
90
  `))>=0){let K=Y.slice(0,W).replace(/\r$/,"");if(Y=Y.slice(W+1),K.startsWith("data:"))V+=`${K.slice(5).trimStart()}
90
- `;else if(!K){let j=z();if(j!==void 0)return Z?.(j),j}}if(G)throw Error("后台激活连接在确认成功前结束")}}catch(H){throw X=H,H}finally{try{await J.cancel()}catch(H){if(X)throw AggregateError([X,H],`${String(X)};响应流关闭失败:${H}`);throw H}finally{J.releaseLock()}}}async function Xz(){let Z=(await Promise.allSettled([...N9.values()].map((J)=>J.close()))).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,`后台激活连接未全部退出:${Z.map(String).join(";")}`)}async function zz($,Z=WD){$.signal.throwIfAborted();let J=Z.createClient($.accountId),Q=new AbortController,Y=()=>Q.abort($.signal.reason);$.signal.addEventListener("abort",Y,{once:!0});let V=setTimeout(()=>Q.abort(Error("后台激活请求超过 60 秒")),60000),X,z,H=!1;try{await J.initialize("lodestar-codex-activation");let G=(await J.request("config/read",{}))?.config;if(G?.cli_auth_credentials_store!=="file")throw Error("零上下文后台激活需要原生文件登录态;当前凭据存储不支持,普通 Codex 会话仍可使用");let W=HD(G.chatgpt_base_url),K=(await J.request("account/read",{refreshToken:!0}))?.account;if(K?.type!=="chatgpt")throw Error("后台激活账号未登录 ChatGPT 订阅");let j=await Z.credentials($.accountId);X=j.accessToken,Q.signal.throwIfAborted();let _=0,D=await h$(()=>{return Q.signal.throwIfAborted(),_=Date.now(),J.request("account/rateLimits/read",{})},"激活前额度确认"),L=M9(D,K.planType,_);if(L.state!=="ok")throw Error(`激活前额度 MISS:${L.state==="network"?L.reason:L.state}`);let P=QD("sha256").update(j.accountId).digest("hex");if(!L.accountFingerprint||L.accountFingerprint!==$.identity||L.accountFingerprint!==P)throw Error("后台激活账号身份与最新额度不一致");if(Q.signal.throwIfAborted(),JZ(L)&&$.eligible(L)){if(Z2(L,Y1)!==L.defaultLimitId)throw Error(`${Y1} 被分配到独立额度,不能用于激活主额度`);let F=await Z.fetch(W,{method:"POST",redirect:"error",signal:Q.signal,headers:{authorization:`Bearer ${X}`,"chatgpt-account-id":j.accountId,"content-type":"application/json",accept:"text/event-stream","OpenAI-Beta":"responses=experimental",originator:"lodestar","user-agent":"lodestar-codex-activation"},body:JSON.stringify(XD($.effort))});await GD(F,(A)=>{H=!0,$.used(L,A)}),Q.signal.throwIfAborted();let U=await Z.refresh(J,$.accountId);if(U?.state!=="ok")throw Error(`额度复核 MISS:${U?.state==="network"?U.reason:U?.state??"读取失败"}`)}}catch(G){let W=G instanceof Error?G.message:String(G),K=X?W.split(X).join("[REDACTED]"):W;z=Error(`${H?"后台激活请求已成功;":""}${K.slice(0,2000)}`)}clearTimeout(V),$.signal.removeEventListener("abort",Y);try{await J.close()}catch(G){z=AggregateError(z?[z,G]:[G],`${z?`${String(z)};`:H?"后台激活请求已成功;":""}后台激活控制连接关闭失败:${G}`)}if(z)throw z;return H?"sent":"skipped"}var Y1="gpt-6-luna",N9,WD;var Hz=N(()=>{j0();J1();J2();p0();J$();N9=new Map;WD={createClient:($)=>{if(N9.has($))throw Error("该账号上次后台激活连接尚未退出");let Z=new N$({accountId:$});return N9.set($,Z),Z.once("exit",()=>{if(N9.get($)===Z)N9.delete($)}),Z},credentials:zD,fetch:V0,refresh:($,Z)=>{return f$(Z),sX((J,Q)=>$.request(J,Q),Z)}}});class Wz{deps;entries=new Map;controller;timer;pending;constructor($){this.deps=$}start(){if(this.controller)return;this.controller=new AbortController,this.schedule(0)}async stop(){clearTimeout(this.timer),this.controller?.abort(Error("服务退出,取消后台激活")),this.controller=void 0;let $=[];try{await this.pending}catch(Z){$.push(Z)}this.entries.clear();try{await this.deps.close?.()}catch(Z){$.push(Z)}if($.length)throw AggregateError($,`后台激活停止失败:${$.map(String).join(";")}`)}error($){return[...this.entries.values()].find((Z)=>Z.accountId===$)?.error}schedule($){if(clearTimeout(this.timer),!this.controller)return;$??=Math.min(BD,...[...this.entries.values()].filter((Z)=>!Z.completed).map((Z)=>Math.max(0,Z.dueAt-this.deps.now()))),this.timer=setTimeout(()=>{this.check().catch((Z)=>this.deps.log(`codex activation scan MISS: ${Z}`)).finally(()=>this.schedule())},$),this.timer.unref?.()}dueAt(){let $=this.deps.random();if(!Number.isFinite($)||$<0||$>=1)throw Error("后台激活随机间隔无效");return this.deps.now()+Gz+Math.floor($*(KD-Gz))}check(){if(this.pending)return this.pending;let $=this.controller?.signal;if(!$||$.aborted)return Promise.resolve();let Z=this.scan($).finally(()=>{if(this.pending===Z)this.pending=void 0});return this.pending=Z,Z}async scan($){let Z=this.deps.accounts(),J=new Set(Z.flatMap((Y)=>Y.usage?.accountFingerprint?[Y.usage.accountFingerprint]:[]));for(let Y of this.entries.keys())if(!J.has(Y))this.entries.delete(Y);let Q=new Set;for(let Y of Z){if($.aborted)return;let V=Y.usage,X=V?.accountFingerprint;if(!V||!X||Q.has(X))continue;Q.add(X);let z=this.entries.get(X);if(!JZ(V)||this.deps.used(X,V)){if(!z?.completed||!z.error||z.revision!==Y.revision)this.entries.delete(X);continue}if(z?.completed)z=void 0;if(!z||z.revision!==Y.revision||z.accountId!==Y.id)z={accountId:Y.id,revision:Y.revision,dueAt:this.dueAt(),completed:!1},this.entries.set(X,z);if(z.completed||this.deps.now()<z.dueAt)continue;z.dueAt=this.dueAt();try{let H=Y.revision;if(this.deps.loginPending(Y.id))throw Error("账号正在登录,后台激活延后");let G=Vz(this.deps.source(Y.id)),W=await this.deps.activate({accountId:Y.id,identity:X,effort:G,signal:$,eligible:(K)=>!$.aborted&&this.deps.accounts().some((j)=>j.id===Y.id&&j.revision===H&&j.usage?.accountFingerprint===X)&&!this.deps.loginPending(Y.id)&&!this.deps.used(X,K),used:(K,j)=>{z.completed=!0,this.deps.recordUsage(Y.id,K),this.deps.log(`codex activation: ${Y.name} ${Y1}/${G} completed tokens=${j}`)}});if(z.error=void 0,W==="skipped")this.deps.log(`codex activation: ${Y.name} skipped after fresh quota/account check`)}catch(H){z.error=H instanceof Error?H.message:String(H),this.deps.log(`codex activation: ${Y.name} MISS: ${z.error}`)}}}}var Gz=1800000,KD=3600000,BD=60000,R9;var QZ=N(()=>{j0();k8();Hz();h();X0();J$();R9=new Wz({accounts:()=>y.list().map(($)=>({id:$.id,name:$.name,revision:y.revision($.id),usage:z2($.id)})),source:($)=>G0("codex-sub",$),loginPending:M1,used:($,Z)=>G2.weekWasUsed($,Z,""),recordUsage:($,Z)=>G2.recordUsage($,Y1,Z),activate:zz,now:Date.now,random:Math.random,log:B,close:Xz})});function g$($){return typeof $==="string"&&YZ.includes($)}function O0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function R0($){return typeof $==="string"&&T9.includes($)}function W4($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function i0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var YZ,T9,T1="max",W2,K4;var _0=N(()=>{YZ=["codex","claude","dsh"];T9=["low","medium","high","xhigh","max","default"];W2=class W2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}};K4=class K4 extends Error{confirmedModel;constructor($,Z,J){super($,J);this.confirmedModel=Z;this.name="ModelSettingsUpdateError"}}});function r($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function K2($,Z){let J=$.agent==="claude"?T9.filter((Y)=>Y!=="default"):$.agent==="codex"?[...Q2]:["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 w8($,Z){let J=$.modelSelection,Q=new Set(r(Z.hidden_models)),Y=[...new Set([...r(Z.custom_models),...J?[]:r(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 z=$.models,H=(J?V.availableModels:z).map((W)=>({...W,origin:W.origin??"upstream"}));for(let W of Y){if(H.some((K)=>K.model.toLowerCase()===W.toLowerCase()))continue;H.push({model:W,display:W,origin:"custom",...K2($,Z)})}V.availableModels=H;let G=J?z.map((W)=>H.find((K)=>K.model===W.model)??{...W,origin:"upstream"}):H;$.models=[...G.filter((W)=>W.origin==="custom"||!Q.has(W.model)),...H.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],V.modelIds=$.models.map((W)=>W.model)},$}var V1=N(()=>{_0();J1()});function E1($){return $.startsWith("claude:")?$:`claude:${$}`}function E9($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(m.claude.models,Z))return m.claude.models[Z]?.model?.trim()||"opus";return Z}var VZ=N(()=>{f0()});import{existsSync as jD,readFileSync as _D}from"node:fs";function XZ(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:LV}function S9(){if(x9!==null)return x9;try{x9=jD(XZ())?JSON.parse(_D(XZ(),"utf8")):{}}catch($){B(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),x9={}}return x9??{}}function LD(){try{a(XZ(),S9())}catch($){B(`context-window-observe: cache write MISS (${$?.message??$})`)}}function zZ($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function Kz($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=zZ($,Z),Y=S9()[Q];if(Y===J)return;S9()[Q]=J,LD(),B(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function v8($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=S9()[zZ($,Z)];return J!=null&&J<PD?Z:`${Z}[1m]`}function B4($,Z){return S9()[zZ($,Z)]}var PD=1e6,x9=null;var C9=N(()=>{H0();h();x0()});var jZ={};r$(jZ,{toolsFromProfile:()=>Rz,settingSourcesFromProfile:()=>Nz,resolveClaudeExecutableConfig:()=>BZ,resetClaudeContextWindowCache:()=>OD,readProjectMcpServers:()=>Tz,readLastCallUsageFromTranscript:()=>Mz,claudeTranscriptPath:()=>I8,claudeTranscriptDir:()=>h8,claudeManagedSkillOptions:()=>Fz,buildClaudeSpawnPath:()=>Uz,assertClaudeCodeAvailable:()=>KZ,ClaudeAgentProcess:()=>g8,CLAUDE_PERMISSION_MODE:()=>Az});import{existsSync as Lz,readFileSync as qz}from"node:fs";import{homedir as f8}from"node:os";import{spawn as qD}from"cross-spawn";import{delimiter as Bz,join as B2}from"node:path";import{EventEmitter as DD}from"node:events";function Fz($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function FD($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function UD($){let Z=qD($.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 KZ(){BZ(),F5("claude","@anthropic-ai/claude-agent-sdk")}function BZ($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?m.claude.bin:$.configuredBin;if(J){if(!($.exists??Lz)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&FD(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:UD,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function Uz(){if(process.platform==="win32")return process.env.PATH??"";let $=[B2(f8(),".local","npm-global","bin"),B2(f8(),".local","bin"),B2(f8(),".bun","bin"),...(process.env.PATH??"").split(Bz),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(Bz)}function MD($){let Z=Q4($);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 jz($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function h8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||B2(f8(),".claude");return B2(J,"projects",Z)}function I8($,Z){return B2(h8($),`${Z}.jsonl`)}function Mz($){let Z;try{Z=qz($,"utf8")}catch{return null}let J=Z.split(`
91
- `);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 _z($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function OD(){GZ.clear()}function AD($){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)+j4(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+j4(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+j4(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+j4(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+j4(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=j4(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 y8($){return{...$}}function HZ($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function ND($,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 j4($){return typeof $==="number"&&Number.isFinite($)?$:0}function Oz($){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(`
92
- `);return $==null?"":JSON.stringify($,null,2)}function RD($){let Z=Oz($);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(`
93
- `)}}catch{}return Z}function TD($){return`server_tool:${$}`}function ED($){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 xD($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function SD($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[T1];return{id:E1($.value),model:E1($.value),displayName:$.displayName||E1($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(T1)?T1:Z[0]}}function Nz($){if(!$?.settingSources)return[...Pz];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...Pz]}function Rz($){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 Tz($){let Z=B2($,".mcp.json"),J;try{J=qz(Z,"utf8")}catch(V){if(V.code==="ENOENT")return;throw Error(`project .mcp.json not readable at ${Z}: ${V}`,{cause:V})}let Q;try{Q=JSON.parse(J)}catch(V){throw Error(`project .mcp.json parse failed at ${Z}: ${V}`,{cause:V})}let Y=Q&&typeof Q==="object"&&!Array.isArray(Q)?Q.mcpServers:void 0;if(!Y||typeof Y!=="object"||Array.isArray(Y))throw Error(`project .mcp.json has no valid mcpServers object at ${Z}`);return Y}function CD($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>bD(Q)).filter((Q)=>Q!==null)}function bD($){let Z=$&&typeof $==="object"?$:{question:$},J=WZ(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=kD(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 kD($){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=WZ(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let V=WZ(Q.description,Q.detail,Q.preview);Z.push(V?{label:Y,description:V}:{label:Y})}return Z}function WZ(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var Dz,GZ,Az="default",Pz,g8;var _4=N(()=>{Z4();f0();h();_0();VZ();C9();Dz=class Dz{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($))}};GZ=new Map;Pz=["project","local"];g8=class g8 extends DD{provider="claude";tokenSourceId;opts;input=new Dz;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?E1($.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 $=E9(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??Nz(Z),Q=Fz(J,this.opts.managedSkillPluginPath),Y=Rz(Z),V=Z?.strictMcp===!0,X=Z?.loadProjectMcp!==!1?Tz(this.opts.workDir):void 0;try{let z=BZ(),{query:H}=await tV();if(!this.alive||this.abortController.signal.aborted)return;let G={...process.env,PATH:Uz(),...m.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=${z.description}`),this.query=H({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}:{},...z.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:z.pathToClaudeCodeExecutable}:{},...z.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:z.spawnClaudeCodeProcess}:{},permissionMode:Az,env:W,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,j,_)=>this.canUseTool(K,j,_),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(K)=>{let j=K.trim();if(j)B(`claude-agent-process[stderr]: ${j}`)}}})}catch(z){let H=z instanceof Error?z:Error(String(z));this.initializationError=H,this.emit("error",H),this.finishExit(1,null);return}if(this.readLoop(this.query),this.opts.validateAccount)try{this.opts.validateAccount(await this.query.accountInfo())}catch(z){this.initializationError=z instanceof Error?z:Error(String(z)),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(" ")+`
94
-
95
- `:"";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(SD)}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=E9($);if(!R0(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 K4(`模型设置未确认:${Q instanceof Error?Q.message:String(Q)}`,null,{cause:Q})}this.opts.model=$,this.lastModel=J?E1($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Q){throw new K4(`模型已切换为 ${$},但思考档位未确认:${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",z)},Y=()=>{if(J)return;J=!0,Q(),$()},V=(H)=>{if(J)return;if((H?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new W2)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},z=(H)=>{if(J)return;J=!0,Q(),Z(H instanceof Error?H:Error(String(H)))};this.on("context_compacted",Y),this.on("assistant_text",V),this.once("exit",X),this.once("error",z)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=CD(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,z={request_id:V,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},H=new Promise((G)=>{let W=(j)=>{J.signal.removeEventListener("abort",K),G(j)},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:z})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",z),H}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=E1($.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=E1(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=ED(Y.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(xD(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,TD(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,RD(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=Oz(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
96
- `):"",z=V||X;this.emitToolResultOnce(Q.tool_use_id,z,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=MD($.usage),J=$.modelUsage??$.model_usage,Q=AD(J);if(!Z&&!Q.usage)B(`claude-agent-process: result usage missing rootKeys=${HZ($).join(",")||"-"} usageKeys=${HZ($.usage).join(",")||"-"} modelUsageKeys=${HZ(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=y8(Q.usage),this.lastTotalUsage=y8(Q.usage);else if(Z)this.cumulativeUsageFromResults=ND(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=y8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?y8(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let z=_z(this.opts.model,this.tokenSourceId);if(GZ.set(z,Q.contextWindow),this.tokenSourceId)for(let[H,G]of Object.entries(J??{})){let W=G?.contextWindow;if(typeof W==="number"&&W>0)Kz(this.tokenSourceId,H,W)}}this.lastContextWindow=GZ.get(_z(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=I8(this.opts.workDir,this.sessionId??""),V=Mz(Y);if(this.lastContextTokens=jz(V)??(Lz(Y)?jz(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(`
97
- `):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})}}});import{homedir as wD}from"node:os";function yD($,Z=vD){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 Ez($){return typeof $==="string"&&fD.includes($)?$:null}async function m8($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (_4(),jZ)),J=new Z({workDir:wD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Q)=>B(`Claude model catalog MISS: ${Q.message}`));try{let Q=await yD(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 xz($="default"){let Z=y.revision($),J=new N$({accountId:$});try{await J.initialize("lodestar-models");let Q=await h$(()=>J.request("account/read",{refreshToken:!1}),"账号查询");if(R8($,Q?.account,Z),Q?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await h$(()=>J.request("model/list",{}),"模型查询");if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let V=Y.data,X=[];for(let z of V){if(!z||z.hidden||!z.id)continue;let H=(Array.isArray(z.supportedReasoningEfforts)?z.supportedReasoningEfforts:[]).map((W)=>Ez(W?.reasoningEffort)).filter((W)=>W!==null);if(!H.length)continue;let G=Ez(z.defaultReasoningEffort)??H[0];X.push({model:String(z.id),display:typeof z.displayName==="string"&&z.displayName?String(z.displayName):String(z.id),efforts:H,defaultEffort:G})}if(!X.length)throw Error("Codex model/list 未返回可用模型");return X}finally{await J.close()}}async function Sz($,Z){return(await r2($,Z)).map((Q)=>({model:Q,display:Q,efforts:P4,defaultEffort:"max"}))}var vD=1e4,fD,P4;var L4=N(()=>{H9();J$();h();T8();j0();fD=["none","minimal","low","medium","high","xhigh","max","ultra"];P4=["max","xhigh","high","medium","low"]});import{existsSync as hD}from"node:fs";import{join as ID}from"node:path";function Cz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function b9($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,credits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(Cz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(Cz($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null,credits:$.credits??null}}function bz($){return $===c||hD(ID(y.home($),"auth.json"))}var p8=N(()=>{f0();X0();J$();L4();h();j0();V1();D0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(Y)=>{let V=bz(Y),X=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,H={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,y.revision(Y)]),enabled:V,models:[],modelCatalogState:{status:V?"idle":"disabled",updatedAt:Date.now()},defaultModel:X??"",async refreshModels(){if(H.enabled=bz(Y),!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{if(H.models=await xz(Y),z)for(let G of H.models)G.defaultEffort=z;if(!X)H.defaultModel=H.models[0]?.model??"";H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(B(`codex-sub ${Y} refreshModels MISS: ${G?.message??G}`),H.models=[],G?.code==="CODEX_AUTH_MISSING")H.enabled=!1;H.modelCatalogState={status:H.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let W=u0(G);return Object.assign(W,m.codex.env),y.env(Y,W)},resolveSpawnModel(G){return G},async readUsage(){return b9(await aX(Y))}};return H},Q=J(c);return Q.forAccount=(Y)=>{if(Y===c)return Q;let V=y.revision(Y),X=Z.get(Y);if(X?.revision===V)return X.source;let z=w8(J(Y),$);return Z.set(Y,{revision:V,source:z}),z},Q}})});function kz($,Z,J){if(!$.enabled||Z.modelCatalogState?.status!=="ready")return;let Q=$.modelSelection,Y=(Z.modelSelection?.availableModels??Z.models).filter((W)=>W.origin!=="custom").map((W)=>({...W,efforts:[...W.efforts]})),V=[...new Set([...r(J.custom_models),...Q?.mode==="catalog"||$.kind.startsWith("packy")?r(J.models):[]])],X=[...Y];for(let W of V)if(!X.some((K)=>K.model.toLowerCase()===W.toLowerCase())){let K=Z.modelSelection?.availableModels.find((j)=>j.model===W);X.push(K?{...K,efforts:[...K.efforts]}:{model:W,display:W,origin:"custom",...K2($,J)})}let z=new Set(r(J.hidden_models)),H=J.models!==void 0?r(J.models):Q?.modelIds.length?Q.modelIds:Z.modelSelection?.modelIds??[],G=Q?.mode==="allowlist"?H.map((W)=>{let K=$.agent==="claude"?W.replace(/\[1m\]$/,""):W,j=X.find((_)=>_.model===K)??Z.models.find((_)=>_.model===W);return j?{...j,model:W}:{model:W,display:W,efforts:[],defaultEffort:null,unavailableReason:"账号目录缓存未返回该模型"}}).filter((W)=>!!W):X.filter((W)=>W.origin==="custom"||!z.has(W.model));if($.models=[...G,...X.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],Q)Q.availableModels=X,Q.modelIds=$.models.map((W)=>W.model);$.defaultModel=J.model?.trim()||(X.some((W)=>W.model===Z.defaultModel)?Z.defaultModel:$.models[0]?.model??""),$.modelCatalogState={...Z.modelCatalogState}}function _Z($,Z,J,Q,Y,V){let X=Y&&k9.get(Y),z=$(),H=z.kind==="codex-subscription"?`${J}:${y.revision(V??c)}`:J;if(X?.active()&&X.configuration===Q&&X.identity===H)return Y;if(X?.identity===H)kz(z,Y,Z);let G={...z},W=!0,K=X?.identity===H?X.snapshot():void 0,j=new Map,_=(P)=>{z=P;let{refreshModels:F,readUsage:U,forAccount:A,...M}=P;Object.assign(G,M)},D=new W8(`token-source ${G.id}${V?`/${V}`:""} models`,gD,async()=>{let P=c8.get(H);if(!P){let O;try{O=$()}catch(w){throw G.modelCatalogState={status:G.modelCatalogState?.status==="ready"?"ready":"failed",updatedAt:G.modelCatalogState?.updatedAt??null,error:w instanceof Error?w.message:String(w)},w}let R=Promise.resolve().then(()=>O.refreshModels()).then(()=>({source:O}),(w)=>({source:O,error:w})).finally(()=>{if(c8.get(H)?.promise===R)c8.delete(H)});P={configuration:Q,promise:R},c8.set(H,P)}let F=await P.promise,U=F.source,A=F.error;if(P.configuration!==Q){if(U=$(),F.source.modelCatalogState?.status==="ready")kz(U,F.source,Z);else if(U.modelCatalogState=F.source.modelCatalogState&&{...F.source.modelCatalogState},!F.source.enabled)U.enabled=!1}if(!W)return;if(A!==void 0&&!U.modelCatalogState?.error)U.modelCatalogState={status:"failed",updatedAt:Date.now(),error:A instanceof Error?A.message:String(A)};let M=U.modelCatalogState?.error;if(M&&l0(M)){if(K={state:"no_credentials",windows:[],reason:M},G.kind==="codex-subscription")f$(V??c)}if(U.modelCatalogState?.status==="failed"||A){let O=U.modelCatalogState?.error??(A instanceof Error?A.message:String(A));if(G.modelCatalogState?.status==="ready"&&!l0(O))G.modelCatalogState={...G.modelCatalogState,error:O};else _(U);throw A??Error(O)}_(U)},X?.identity===H?X.model.nextRefreshAt:0),L=new W8(`token-source ${G.id}${V?`/${V}`:""} usage`,mD,async()=>{let P;try{P=await z.readUsage()}catch(F){let U=F instanceof Error?F.message:String(F);if(W&&(K?.state!=="ok"||l0(U)))K={state:l0(U)?"no_credentials":"network",windows:[],reason:U};throw F}if(!W)return;if(K?.state!=="ok"||!["network","rate_limited"].includes(P.state)||l0(P.reason))K=P;if(P.state!=="ok"&&P.state!=="not_applicable"&&P.state!=="no_credentials")throw Object.assign(Error(P.reason??P.state),{retryAfterMs:P.retryAfterMs})},X?.identity===H?X.usage.nextRefreshAt:0);if(G.refreshModels=()=>D.refresh(),G.readUsage=async()=>!G.enabled?{state:"no_credentials",windows:[],reason:G.modelCatalogState?.error}:G.kind==="codex-subscription"?b9(X2(V)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}):K??{state:G.enabled?"network":"no_credentials",windows:[],reason:"额度缓存尚未就绪,后台刷新中"},z.forAccount)G.forAccount=(P)=>{if(P===c)return G;let F=y.revision(P),U=j.get(P);if(U?.revision===F)return U.source;if(U)w9(U.source);let A=X?.baseIdentity===J?X.children.get(P):void 0,M=_Z(()=>$().forAccount(P),Z,J,Q,A?.revision===F?A.source:void 0,P);return j.set(P,{revision:F,source:M}),M};return k9.set(G,{baseIdentity:J,identity:H,configuration:Q,model:D,usage:L,children:j,snapshot:()=>K,active:()=>W,dispose(){W=!1,D.dispose(),L.dispose();for(let P of j.values())w9(P.source)}}),G}function w9($){k9.get($)?.dispose()}function wz($,Z){let J=$&&k9.get($),Q=J?.children.get(Z);if(Q)w9(Q.source),J.children.delete(Z)}function vz($){return k9.get($)?.usage.refresh()??Promise.resolve()}var gD=300000,mD=60000,k9,c8;var l8=N(()=>{N5();j0();V1();J$();p8();Q1();k9=new WeakMap,c8=new Map});function cD($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!pD.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 y9{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 yz($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class LZ{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 PZ($){if(Array.isArray($))return`[${$.map(PZ).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)}:${PZ(J)}`).join(",")}}`}function lD($){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${PZ(V)}`}function uD($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${lD($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function dD(){return new Promise(($)=>setTimeout($,0))}function v9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function fz($){let Z=$.afterAck??dD,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=cD(Y);if(V)return $.responses.invalid(Y,V);let X=uD(Y),z=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],H=$.deduper.claimAll(z);if(H==="inflight")return $.responses.inflight(Y);if(H==="completed")return $.responses.completed(Y);let G=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(j){$.deduper.failAll(z),J(j);return}let W;try{W=await $.execute(Y)}catch(j){v9($.deduper,X,!0),await Q(()=>$.presentExecutionFailure(Y,j));return}await Q(async()=>{try{await $.present(Y,W)}catch(j){await $.presentPresentationFailure(Y,j)}});let K;try{K=$.completion(Y,W)}catch(j){v9($.deduper,X,!1),J(j);return}if(K){let j=K.then((_)=>{v9($.deduper,X,_==="complete")},(_)=>{v9($.deduper,X,!1),J(_)});$.track(j);return}v9($.deduper,X,$.businessSucceeded(Y,W))});if(!G.accepted)return $.deduper.failAll(z),$.responses.closed(Y);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Y)}}}var pD;var qZ=N(()=>{pD=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 iD}from"node:async_hooks";class hz{actor=new y9;context=new iD;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 R$($,Z){return nD.run($,Z)}var nD;var DZ=N(()=>{qZ();nD=new hz});import{execFileSync as aD}from"node:child_process";import{existsSync as x1,readdirSync as oD,readFileSync as sD,realpathSync as d8,statSync as tD}from"node:fs";import{dirname as rD,join as gz,resolve as eD}from"node:path";async function i8($,Z){let J=d8($),Q=process.platform==="win32"?J.toLowerCase():J,Y=u8.get(Q)??Promise.resolve(),V,X=new Promise((H)=>{V=H}),z=Y.catch(()=>{}).then(()=>X);u8.set(Q,z),await Y.catch(()=>{});try{return await Z()}finally{if(V(),u8.get(Q)===z)u8.delete(Q)}}function j2($){let Z=$.trim();if(!$F.test(Z))return null;return Z}function n8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function D4($,Z){return`${$}[${Z}]`}function mz($){return`${q4}${$}`}function F4($,Z,J){return gz(rD($),D4(Z,J))}function pz($,Z,J){let Q=ZF($,Z,J);if(!Q)return null;let Y=sD(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function cz($,Z){UZ($);let J=b0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${q4}`]).split(`
98
- `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(q4)),Q=MZ($),Y=[];for(let V of J){let X=V.slice(q4.length);if(!j2(X))continue;let z=D4(Z,X),H=F4($,Z,X),G=Q.get(V)??null,W=!!G&&x1(G),K=iz($,V,W),j={slug:X,chatName:z,branch:V,state:K,expectedPath:H,worktreePath:W?G:null,mounted:W,dirtyCount:null,statusLine:null,error:null};if(G&&x1(G))try{let D=b0(G,["status","--porcelain=v1","--branch"]).split(`
99
- `).filter(Boolean);j.statusLine=D[0]?.startsWith("## ")?D[0].slice(3):null,j.dirtyCount=D.filter((L)=>!L.startsWith("## ")).length}catch(_){j.error=AZ(_)}Y.push(j)}return Y.sort((V,X)=>V.slug.localeCompare(X.slug))}function lz($,Z,J){let Q=j2(J);if(!Q)throw Error(`invalid worktree name "${J}"`);UZ($);let Y=mz(Q),V=D4(Z,Q),X=F4($,Z,Q),z=VF($,Y),H=MZ($).get(Y)??null,G=z&&!H&&iz($,Y,!1)==="merged"?b0($,["rev-parse","HEAD"]).trim():null;if(H){if(!OZ(H,X))throw Error(`branch ${Y} is already mounted at ${H}`);return dz(X,Y),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(x1(X)){if(!tD(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!z)throw Error(`${X} already exists while branch ${Y} does not`)}if(z){if(b0($,["worktree","add",X,Y]),G)b0(X,["rebase",G]);return{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return b0($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function uz($,Z,J){let Q=FZ($,Z,J);if(!x1(Q.worktreePath))return Q;return b0($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function FZ($,Z,J){let Q=j2(J);if(!Q)throw Error(`invalid worktree name "${J}"`);UZ($);let Y=mz(Q),V=D4(Z,Q),X=F4($,Z,Q),z=MZ($).get(Y)??null;if(z&&!OZ(z,X))throw Error(`branch ${Y} is already mounted at ${z}, outside managed path ${X}`);let H=z??X;if(!x1(H))return{slug:Q,chatName:V,branch:Y,worktreePath:H,removedWorktree:!1};if(!z)throw Error(`${H} is not a registered worktree of ${$}`);dz(H,Y);let G=b0(H,["status","--porcelain=v1"]).split(`
91
+ `;else if(!K){let j=z();if(j!==void 0)return Z?.(j),j}}if(G)throw Error("后台激活连接在确认成功前结束")}}catch(H){throw X=H,H}finally{try{await J.cancel()}catch(H){if(X)throw AggregateError([X,H],`${String(X)};响应流关闭失败:${H}`);throw H}finally{J.releaseLock()}}}async function jz(){let Z=(await Promise.allSettled([...R9.values()].map((J)=>J.close()))).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,`后台激活连接未全部退出:${Z.map(String).join(";")}`)}async function _z($,Z=ND){$.signal.throwIfAborted();let J=Z.createClient($.accountId),Q=new AbortController,Y=()=>Q.abort($.signal.reason);$.signal.addEventListener("abort",Y,{once:!0});let V=setTimeout(()=>Q.abort(Error("后台激活请求超过 60 秒")),60000),X,z,H=!1;try{await J.initialize("lodestar-codex-activation");let G=(await J.request("config/read",{}))?.config;if(G?.cli_auth_credentials_store!=="file")throw Error("零上下文后台激活需要原生文件登录态;当前凭据存储不支持,普通 Codex 会话仍可使用");let W=OD(G.chatgpt_base_url),K=(await J.request("account/read",{refreshToken:!0}))?.account;if(K?.type!=="chatgpt")throw Error("后台激活账号未登录 ChatGPT 订阅");let j=await Z.credentials($.accountId);X=j.accessToken,Q.signal.throwIfAborted();let _=0,D=await h$(()=>{return Q.signal.throwIfAborted(),_=Date.now(),J.request("account/rateLimits/read",{})},"激活前额度确认"),P=O9(D,K.planType,_);if(P.state!=="ok")throw Error(`激活前额度 MISS:${P.state==="network"?P.reason:P.state}`);let L=qD("sha256").update(j.accountId).digest("hex");if(!P.accountFingerprint||P.accountFingerprint!==$.identity||P.accountFingerprint!==L)throw Error("后台激活账号身份与最新额度不一致");if(Q.signal.throwIfAborted(),QZ(P)&&$.eligible(P)){if(J2(P,Y1)!==P.defaultLimitId)throw Error(`${Y1} 被分配到独立额度,不能用于激活主额度`);let F=await Z.fetch(W,{method:"POST",redirect:"error",signal:Q.signal,headers:{authorization:`Bearer ${X}`,"chatgpt-account-id":j.accountId,"content-type":"application/json",accept:"text/event-stream","OpenAI-Beta":"responses=experimental",originator:"lodestar","user-agent":"lodestar-codex-activation"},body:JSON.stringify(UD($.effort))});await AD(F,(A)=>{H=!0,$.used(P,A)}),Q.signal.throwIfAborted();let U=await Z.refresh(J,$.accountId);if(U?.state!=="ok")throw Error(`额度复核 MISS:${U?.state==="network"?U.reason:U?.state??"读取失败"}`)}}catch(G){let W=G instanceof Error?G.message:String(G),K=X?W.split(X).join("[REDACTED]"):W;z=Error(`${H?"后台激活请求已成功;":""}${K.slice(0,2000)}`)}clearTimeout(V),$.signal.removeEventListener("abort",Y);try{await J.close()}catch(G){z=AggregateError(z?[z,G]:[G],`${z?`${String(z)};`:H?"后台激活请求已成功;":""}后台激活控制连接关闭失败:${G}`)}if(z)throw z;return H?"sent":"skipped"}var Y1="gpt-6-luna",R9,ND;var Lz=R(()=>{j0();J1();Q2();p0();J$();R9=new Map;ND={createClient:($)=>{if(R9.has($))throw Error("该账号上次后台激活连接尚未退出");let Z=new N$({accountId:$});return R9.set($,Z),Z.once("exit",()=>{if(R9.get($)===Z)R9.delete($)}),Z},credentials:MD,fetch:X0,refresh:($,Z)=>{return f$(Z),Qz((J,Q)=>$.request(J,Q),Z)}}});class qz{deps;entries=new Map;controller;timer;pending;constructor($){this.deps=$}start(){if(this.controller)return;this.controller=new AbortController,this.schedule(0)}async stop(){clearTimeout(this.timer),this.controller?.abort(Error("服务退出,取消后台激活")),this.controller=void 0;let $=[];try{await this.pending}catch(Z){$.push(Z)}this.entries.clear();try{await this.deps.close?.()}catch(Z){$.push(Z)}if($.length)throw AggregateError($,`后台激活停止失败:${$.map(String).join(";")}`)}error($){return[...this.entries.values()].find((Z)=>Z.accountId===$)?.error}schedule($){if(clearTimeout(this.timer),!this.controller)return;$??=Math.min(TD,...[...this.entries.values()].filter((Z)=>!Z.completed).map((Z)=>Math.max(0,Z.dueAt-this.deps.now()))),this.timer=setTimeout(()=>{this.check().catch((Z)=>this.deps.log(`codex activation scan MISS: ${Z}`)).finally(()=>this.schedule())},$),this.timer.unref?.()}dueAt(){let $=this.deps.random();if(!Number.isFinite($)||$<0||$>=1)throw Error("后台激活随机间隔无效");return this.deps.now()+Pz+Math.floor($*(RD-Pz))}check(){if(this.pending)return this.pending;let $=this.controller?.signal;if(!$||$.aborted)return Promise.resolve();let Z=this.scan($).finally(()=>{if(this.pending===Z)this.pending=void 0});return this.pending=Z,Z}async scan($){let Z=this.deps.accounts(),J=new Set(Z.flatMap((Y)=>Y.usage?.accountFingerprint?[Y.usage.accountFingerprint]:[]));for(let Y of this.entries.keys())if(!J.has(Y))this.entries.delete(Y);let Q=new Set;for(let Y of Z){if($.aborted)return;let V=Y.usage,X=V?.accountFingerprint;if(!V||!X||Q.has(X))continue;Q.add(X);let z=this.entries.get(X);if(!QZ(V)||this.deps.used(X,V)){if(!z?.completed||!z.error||z.revision!==Y.revision)this.entries.delete(X);continue}if(z?.completed)z=void 0;if(!z||z.revision!==Y.revision||z.accountId!==Y.id)z={accountId:Y.id,revision:Y.revision,dueAt:this.dueAt(),completed:!1},this.entries.set(X,z);if(z.completed||this.deps.now()<z.dueAt)continue;z.dueAt=this.dueAt();try{let H=Y.revision;if(this.deps.loginPending(Y.id))throw Error("账号正在登录,后台激活延后");let G=Bz(this.deps.source(Y.id)),W=await this.deps.activate({accountId:Y.id,identity:X,effort:G,signal:$,eligible:(K)=>!$.aborted&&this.deps.accounts().some((j)=>j.id===Y.id&&j.revision===H&&j.usage?.accountFingerprint===X)&&!this.deps.loginPending(Y.id)&&!this.deps.used(X,K),used:(K,j)=>{z.completed=!0,this.deps.recordUsage(Y.id,K),this.deps.log(`codex activation: ${Y.name} ${Y1}/${G} completed tokens=${j}`)}});if(z.error=void 0,W==="skipped")this.deps.log(`codex activation: ${Y.name} skipped after fresh quota/account check`)}catch(H){z.error=H instanceof Error?H.message:String(H),this.deps.log(`codex activation: ${Y.name} MISS: ${z.error}`)}}}}var Pz=1800000,RD=3600000,TD=60000,T9;var YZ=R(()=>{j0();w8();Lz();h();z0();J$();T9=new qz({accounts:()=>v.list().map(($)=>({id:$.id,name:$.name,revision:v.revision($.id),usage:H2($.id)})),source:($)=>G0("codex-sub",$),loginPending:M1,used:($,Z)=>W2.weekWasUsed($,Z,""),recordUsage:($,Z)=>W2.recordUsage($,Y1,Z),activate:_z,now:Date.now,random:Math.random,log:B,close:jz})});function g$($){return typeof $==="string"&&VZ.includes($)}function O0($){return typeof $==="string"&&["off","minimal","low","medium","high","xhigh","max"].includes($)}function R0($){return typeof $==="string"&&E9.includes($)}function W4($){if($?.startsWith("dsh:"))return"dsh";return $?.startsWith("claude:")?"claude":"codex"}function i0($){return{claude:"Claude",codex:"Codex",dsh:"DeepSeek Harness"}[$]}var VZ,E9,T1="max",K2,K4;var _0=R(()=>{VZ=["codex","claude","dsh"];E9=["low","medium","high","xhigh","max","default"];K2=class K2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}};K4=class K4 extends Error{confirmedModel;constructor($,Z,J){super($,J);this.confirmedModel=Z;this.name="ModelSettingsUpdateError"}}});function r($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function B2($,Z){let J=$.agent==="claude"?E9.filter((Y)=>Y!=="default"):$.agent==="codex"?[...Y2]:["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 v8($,Z){let J=$.modelSelection,Q=new Set(r(Z.hidden_models)),Y=[...new Set([...r(Z.custom_models),...J?[]:r(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 z=$.models,H=(J?V.availableModels:z).map((W)=>({...W,origin:W.origin??"upstream"}));for(let W of Y){if(H.some((K)=>K.model.toLowerCase()===W.toLowerCase()))continue;H.push({model:W,display:W,origin:"custom",...B2($,Z)})}V.availableModels=H;let G=J?z.map((W)=>H.find((K)=>K.model===W.model)??{...W,origin:"upstream"}):H;$.models=[...G.filter((W)=>W.origin==="custom"||!Q.has(W.model)),...H.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],V.modelIds=$.models.map((W)=>W.model)},$}var V1=R(()=>{_0();J1()});function E1($){return $.startsWith("claude:")?$:`claude:${$}`}function x9($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(m.claude.models,Z))return m.claude.models[Z]?.model?.trim()||"opus";return Z}var XZ=R(()=>{f0()});import{existsSync as ED,readFileSync as xD}from"node:fs";function zZ(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:DV}function C9(){if(S9!==null)return S9;try{S9=ED(zZ())?JSON.parse(xD(zZ(),"utf8")):{}}catch($){B(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),S9={}}return S9??{}}function CD(){try{a(zZ(),C9())}catch($){B(`context-window-observe: cache write MISS (${$?.message??$})`)}}function HZ($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function Dz($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=HZ($,Z),Y=C9()[Q];if(Y===J)return;C9()[Q]=J,CD(),B(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function y8($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=C9()[HZ($,Z)];return J!=null&&J<SD?Z:`${Z}[1m]`}function B4($,Z){return C9()[HZ($,Z)]}var SD=1e6,S9=null;var b9=R(()=>{H0();h();x0()});var _Z={};r$(_Z,{toolsFromProfile:()=>kz,settingSourcesFromProfile:()=>bz,resolveClaudeExecutableConfig:()=>jZ,resetClaudeContextWindowCache:()=>fD,readProjectMcpServers:()=>wz,readLastCallUsageFromTranscript:()=>xz,claudeTranscriptPath:()=>g8,claudeTranscriptDir:()=>I8,claudeManagedSkillOptions:()=>Tz,buildClaudeSpawnPath:()=>Ez,assertClaudeCodeAvailable:()=>BZ,ClaudeAgentProcess:()=>m8,CLAUDE_PERMISSION_MODE:()=>Cz});import{existsSync as Az,readFileSync as Nz}from"node:fs";import{homedir as h8}from"node:os";import{spawn as bD}from"cross-spawn";import{delimiter as Fz,join as j2}from"node:path";import{EventEmitter as kD}from"node:events";function Tz($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function wD($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function vD($){let Z=bD($.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 BZ(){jZ(),U5("claude","@anthropic-ai/claude-agent-sdk")}function jZ($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?m.claude.bin:$.configuredBin;if(J){if(!($.exists??Az)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&wD(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:vD,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function Ez(){if(process.platform==="win32")return process.env.PATH??"";let $=[j2(h8(),".local","npm-global","bin"),j2(h8(),".local","bin"),j2(h8(),".bun","bin"),...(process.env.PATH??"").split(Fz),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(Fz)}function yD($){let Z=Q4($);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 Uz($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function I8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||j2(h8(),".claude");return j2(J,"projects",Z)}function g8($,Z){return j2(I8($),`${Z}.jsonl`)}function xz($){let Z;try{Z=Nz($,"utf8")}catch{return null}let J=Z.split(`
92
+ `);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 Mz($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function fD(){WZ.clear()}function hD($){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)+j4(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+j4(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+j4(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+j4(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+j4(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=j4(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 f8($){return{...$}}function GZ($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function ID($,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 j4($){return typeof $==="number"&&Number.isFinite($)?$:0}function Sz($){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(`
93
+ `);return $==null?"":JSON.stringify($,null,2)}function gD($){let Z=Sz($);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(`
94
+ `)}}catch{}return Z}function mD($){return`server_tool:${$}`}function pD($){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 cD($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function lD($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[T1];return{id:E1($.value),model:E1($.value),displayName:$.displayName||E1($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(T1)?T1:Z[0]}}function bz($){if(!$?.settingSources)return[...Oz];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...Oz]}function kz($){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 wz($){let Z=j2($,".mcp.json"),J;try{J=Nz(Z,"utf8")}catch(V){if(V.code==="ENOENT")return;throw Error(`project .mcp.json not readable at ${Z}: ${V}`,{cause:V})}let Q;try{Q=JSON.parse(J)}catch(V){throw Error(`project .mcp.json parse failed at ${Z}: ${V}`,{cause:V})}let Y=Q&&typeof Q==="object"&&!Array.isArray(Q)?Q.mcpServers:void 0;if(!Y||typeof Y!=="object"||Array.isArray(Y))throw Error(`project .mcp.json has no valid mcpServers object at ${Z}`);return Y}function uD($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>dD(Q)).filter((Q)=>Q!==null)}function dD($){let Z=$&&typeof $==="object"?$:{question:$},J=KZ(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=iD(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 iD($){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=KZ(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let V=KZ(Q.description,Q.detail,Q.preview);Z.push(V?{label:Y,description:V}:{label:Y})}return Z}function KZ(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var Rz,WZ,Cz="default",Oz,m8;var _4=R(()=>{Z4();f0();h();_0();XZ();b9();Rz=class Rz{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($))}};WZ=new Map;Oz=["project","local"];m8=class m8 extends kD{provider="claude";tokenSourceId;opts;input=new Rz;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?E1($.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 $=x9(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??bz(Z),Q=Tz(J,this.opts.managedSkillPluginPath),Y=kz(Z),V=[...this.opts.allowDelegation===!1?["Agent","Task","Workflow"]:[],...this.opts.allowUserInput===!1?["AskUserQuestion","EnterPlanMode","ExitPlanMode"]:[]],X=Z?.strictMcp===!0,z=Z?.loadProjectMcp!==!1?wz(this.opts.workDir):void 0;try{let H=jZ(),{query:G}=await eV();if(!this.alive||this.abortController.signal.aborted)return;let W={...process.env,PATH:Ez(),...m.claude.env,...this.opts.hostEnv??{}},K=this.opts.transformEnv?this.opts.transformEnv(W):W;if(K.CLAUDE_CODE_ENABLE_TODO_TOOLS="1",this.opts.effort==="default")K.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=G({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:Cz,env:K,settingSources:[...J],...this.opts.settings?{settings:this.opts.settings}:{},...Q,tools:Y,...V.length?{disallowedTools:V}:{},...X?{strictMcpConfig:!0}:{},...z?{mcpServers:z}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(j,_,D)=>this.canUseTool(j,_,D),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt,snapshot:!1}:{}},stderr:(j)=>{let _=j.trim();if(_)B(`claude-agent-process[stderr]: ${_}`)}}})}catch(H){let G=H instanceof Error?H:Error(String(H));this.initializationError=G,this.emit("error",G),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(" ")+`
95
+
96
+ `:"";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(lD)}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=x9($);if(!R0(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 K4(`模型设置未确认:${Q instanceof Error?Q.message:String(Q)}`,null,{cause:Q})}this.opts.model=$,this.lastModel=J?E1($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Q){throw new K4(`模型已切换为 ${$},但思考档位未确认:${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",z)},Y=()=>{if(J)return;J=!0,Q(),$()},V=(H)=>{if(J)return;if((H?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new K2)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},z=(H)=>{if(J)return;J=!0,Q(),Z(H instanceof Error?H:Error(String(H)))};this.on("context_compacted",Y),this.on("assistant_text",V),this.once("exit",X),this.once("error",z)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=uD(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,z={request_id:V,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},H=new Promise((G)=>{let W=(j)=>{J.signal.removeEventListener("abort",K),G(j)},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:z})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",z),H}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=E1($.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=E1(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=pD(Y.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(cD(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,mD(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,gD(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=Sz(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
97
+ `):"",z=V||X;this.emitToolResultOnce(Q.tool_use_id,z,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=yD($.usage),J=$.modelUsage??$.model_usage,Q=hD(J);if(!Z&&!Q.usage)B(`claude-agent-process: result usage missing rootKeys=${GZ($).join(",")||"-"} usageKeys=${GZ($.usage).join(",")||"-"} modelUsageKeys=${GZ(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=f8(Q.usage),this.lastTotalUsage=f8(Q.usage);else if(Z)this.cumulativeUsageFromResults=ID(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=f8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?f8(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let z=Mz(this.opts.model,this.tokenSourceId);if(WZ.set(z,Q.contextWindow),this.tokenSourceId)for(let[H,G]of Object.entries(J??{})){let W=G?.contextWindow;if(typeof W==="number"&&W>0)Dz(this.tokenSourceId,H,W)}}this.lastContextWindow=WZ.get(Mz(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=g8(this.opts.workDir,this.sessionId??""),V=xz(Y);if(this.lastContextTokens=Uz(V)??(Az(Y)?Uz(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(`
98
+ `):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})}}});import{homedir as nD}from"node:os";function oD($,Z=aD){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 vz($){return typeof $==="string"&&sD.includes($)?$:null}async function p8($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (_4(),_Z)),J=new Z({workDir:nD(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Q)=>B(`Claude model catalog MISS: ${Q.message}`));try{let Q=await oD(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=v.revision($),J=new N$({accountId:$});try{await J.initialize("lodestar-models");let Q=await h$(()=>J.request("account/read",{refreshToken:!1}),"账号查询");if(T8($,Q?.account,Z),Q?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await h$(()=>J.request("model/list",{}),"模型查询");if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let V=Y.data,X=[];for(let z of V){if(!z||z.hidden||!z.id)continue;let H=(Array.isArray(z.supportedReasoningEfforts)?z.supportedReasoningEfforts:[]).map((W)=>vz(W?.reasoningEffort)).filter((W)=>W!==null);if(!H.length)continue;let G=vz(z.defaultReasoningEffort)??H[0];X.push({model:String(z.id),display:typeof z.displayName==="string"&&z.displayName?String(z.displayName):String(z.id),efforts:H,defaultEffort:G})}if(!X.length)throw Error("Codex model/list 未返回可用模型");return X}finally{await J.close()}}async function fz($,Z){return(await r2($,Z)).map((Q)=>({model:Q,display:Q,efforts:L4,defaultEffort:"max"}))}var aD=1e4,sD,L4;var P4=R(()=>{G9();J$();h();E8();j0();sD=["none","minimal","low","medium","high","xhigh","max","ultra"];L4=["max","xhigh","high","medium","low"]});import{existsSync as tD}from"node:fs";import{join as rD}from"node:path";function hz($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function k9($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,credits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(hz($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(hz($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null,credits:$.credits??null}}function Iz($){return $===l||tD(rD(v.home($),"auth.json"))}var c8=R(()=>{f0();z0();J$();P4();h();j0();V1();D0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(Y)=>{let V=Iz(Y),X=$.model?.trim()||void 0,z=$.effort?.trim()||void 0,H={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",spawnRevision:JSON.stringify([$.model,$.effort,v.revision(Y)]),enabled:V,models:[],modelCatalogState:{status:V?"idle":"disabled",updatedAt:Date.now()},defaultModel:X??"",async refreshModels(){if(H.enabled=Iz(Y),!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{if(H.models=await yz(Y),z)for(let G of H.models)G.defaultEffort=z;if(!X)H.defaultModel=H.models[0]?.model??"";H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(B(`codex-sub ${Y} refreshModels MISS: ${G?.message??G}`),H.models=[],G?.code==="CODEX_AUTH_MISSING")H.enabled=!1;H.modelCatalogState={status:H.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let W=u0(G);return Object.assign(W,m.codex.env),v.env(Y,W)},resolveSpawnModel(G){return G},async readUsage(){return k9(await Zz(Y))}};return H},Q=J(l);return Q.forAccount=(Y)=>{if(Y===l)return Q;let V=v.revision(Y),X=Z.get(Y);if(X?.revision===V)return X.source;let z=v8(J(Y),$);return Z.set(Y,{revision:V,source:z}),z},Q}})});function gz($,Z,J){if(!$.enabled||Z.modelCatalogState?.status!=="ready")return;let Q=$.modelSelection,Y=(Z.modelSelection?.availableModels??Z.models).filter((W)=>W.origin!=="custom").map((W)=>({...W,efforts:[...W.efforts]})),V=[...new Set([...r(J.custom_models),...Q?.mode==="catalog"||$.kind.startsWith("packy")?r(J.models):[]])],X=[...Y];for(let W of V)if(!X.some((K)=>K.model.toLowerCase()===W.toLowerCase())){let K=Z.modelSelection?.availableModels.find((j)=>j.model===W);X.push(K?{...K,efforts:[...K.efforts]}:{model:W,display:W,origin:"custom",...B2($,J)})}let z=new Set(r(J.hidden_models)),H=J.models!==void 0?r(J.models):Q?.modelIds.length?Q.modelIds:Z.modelSelection?.modelIds??[],G=Q?.mode==="allowlist"?H.map((W)=>{let K=$.agent==="claude"?W.replace(/\[1m\]$/,""):W,j=X.find((_)=>_.model===K)??Z.models.find((_)=>_.model===W);return j?{...j,model:W}:{model:W,display:W,efforts:[],defaultEffort:null,unavailableReason:"账号目录缓存未返回该模型"}}).filter((W)=>!!W):X.filter((W)=>W.origin==="custom"||!z.has(W.model));if($.models=[...G,...X.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],Q)Q.availableModels=X,Q.modelIds=$.models.map((W)=>W.model);$.defaultModel=J.model?.trim()||(X.some((W)=>W.model===Z.defaultModel)?Z.defaultModel:$.models[0]?.model??""),$.modelCatalogState={...Z.modelCatalogState}}function LZ($,Z,J,Q,Y,V){let X=Y&&w9.get(Y),z=$(),H=z.kind==="codex-subscription"?`${J}:${v.revision(V??l)}`:J;if(X?.active()&&X.configuration===Q&&X.identity===H)return Y;if(X?.identity===H)gz(z,Y,Z);let G={...z},W=!0,K=X?.identity===H?X.snapshot():void 0,j=new Map,_=(L)=>{z=L;let{refreshModels:F,readUsage:U,forAccount:A,...M}=L;Object.assign(G,M)},D=new K8(`token-source ${G.id}${V?`/${V}`:""} models`,eD,async()=>{let L=l8.get(H);if(!L){let O;try{O=$()}catch(k){throw G.modelCatalogState={status:G.modelCatalogState?.status==="ready"?"ready":"failed",updatedAt:G.modelCatalogState?.updatedAt??null,error:k instanceof Error?k.message:String(k)},k}let T=Promise.resolve().then(()=>O.refreshModels()).then(()=>({source:O}),(k)=>({source:O,error:k})).finally(()=>{if(l8.get(H)?.promise===T)l8.delete(H)});L={configuration:Q,promise:T},l8.set(H,L)}let F=await L.promise,U=F.source,A=F.error;if(L.configuration!==Q){if(U=$(),F.source.modelCatalogState?.status==="ready")gz(U,F.source,Z);else if(U.modelCatalogState=F.source.modelCatalogState&&{...F.source.modelCatalogState},!F.source.enabled)U.enabled=!1}if(!W)return;if(A!==void 0&&!U.modelCatalogState?.error)U.modelCatalogState={status:"failed",updatedAt:Date.now(),error:A instanceof Error?A.message:String(A)};let M=U.modelCatalogState?.error;if(M&&l0(M)){if(K={state:"no_credentials",windows:[],reason:M},G.kind==="codex-subscription")f$(V??l)}if(U.modelCatalogState?.status==="failed"||A){let O=U.modelCatalogState?.error??(A instanceof Error?A.message:String(A));if(G.modelCatalogState?.status==="ready"&&!l0(O))G.modelCatalogState={...G.modelCatalogState,error:O};else _(U);throw A??Error(O)}_(U)},X?.identity===H?X.model.nextRefreshAt:0),P=new K8(`token-source ${G.id}${V?`/${V}`:""} usage`,$F,async()=>{let L;try{L=await z.readUsage()}catch(F){let U=F instanceof Error?F.message:String(F);if(W&&(K?.state!=="ok"||l0(U)))K={state:l0(U)?"no_credentials":"network",windows:[],reason:U};throw F}if(!W)return;if(K?.state!=="ok"||!["network","rate_limited"].includes(L.state)||l0(L.reason))K=L;if(L.state!=="ok"&&L.state!=="not_applicable"&&L.state!=="no_credentials")throw Object.assign(Error(L.reason??L.state),{retryAfterMs:L.retryAfterMs})},X?.identity===H?X.usage.nextRefreshAt:0);if(G.refreshModels=()=>D.refresh(),G.readUsage=async()=>!G.enabled?{state:"no_credentials",windows:[],reason:G.modelCatalogState?.error}:G.kind==="codex-subscription"?k9(z2(V)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}):K??{state:G.enabled?"network":"no_credentials",windows:[],reason:"额度缓存尚未就绪,后台刷新中"},z.forAccount)G.forAccount=(L)=>{if(L===l)return G;let F=v.revision(L),U=j.get(L);if(U?.revision===F)return U.source;if(U)v9(U.source);let A=X?.baseIdentity===J?X.children.get(L):void 0,M=LZ(()=>$().forAccount(L),Z,J,Q,A?.revision===F?A.source:void 0,L);return j.set(L,{revision:F,source:M}),M};return w9.set(G,{baseIdentity:J,identity:H,configuration:Q,model:D,usage:P,children:j,snapshot:()=>K,active:()=>W,dispose(){W=!1,D.dispose(),P.dispose();for(let L of j.values())v9(L.source)}}),G}function v9($){w9.get($)?.dispose()}function mz($,Z){let J=$&&w9.get($),Q=J?.children.get(Z);if(Q)v9(Q.source),J.children.delete(Z)}function pz($){return w9.get($)?.usage.refresh()??Promise.resolve()}var eD=300000,$F=60000,w9,l8;var u8=R(()=>{R5();j0();V1();J$();c8();Q1();w9=new WeakMap,l8=new Map});function JF($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!ZF.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 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 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 cz($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class qZ{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 PZ($){if(Array.isArray($))return`[${$.map(PZ).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)}:${PZ(J)}`).join(",")}}`}function QF($){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${PZ(V)}`}function YF($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${QF($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function VF(){return new Promise(($)=>setTimeout($,0))}function y9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function lz($){let Z=$.afterAck??VF,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=JF(Y);if(V)return $.responses.invalid(Y,V);let X=YF(Y),z=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],H=$.deduper.claimAll(z);if(H==="inflight")return $.responses.inflight(Y);if(H==="completed")return $.responses.completed(Y);let G=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(j){$.deduper.failAll(z),J(j);return}let W;try{W=await $.execute(Y)}catch(j){y9($.deduper,X,!0),await Q(()=>$.presentExecutionFailure(Y,j));return}await Q(async()=>{try{await $.present(Y,W)}catch(j){await $.presentPresentationFailure(Y,j)}});let K;try{K=$.completion(Y,W)}catch(j){y9($.deduper,X,!1),J(j);return}if(K){let j=K.then((_)=>{y9($.deduper,X,_==="complete")},(_)=>{y9($.deduper,X,!1),J(_)});$.track(j);return}y9($.deduper,X,$.businessSucceeded(Y,W))});if(!G.accepted)return $.deduper.failAll(z),$.responses.closed(Y);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Y)}}}var ZF;var DZ=R(()=>{ZF=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 XF}from"node:async_hooks";class uz{actor=new f9;context=new XF;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 R$($,Z){return zF.run($,Z)}var zF;var FZ=R(()=>{DZ();zF=new uz});import{execFileSync as HF}from"node:child_process";import{existsSync as x1,readdirSync as GF,readFileSync as WF,realpathSync as i8,statSync as KF}from"node:fs";import{dirname as BF,join as iz,resolve as jF}from"node:path";async function n8($,Z){let J=i8($),Q=process.platform==="win32"?J.toLowerCase():J,Y=d8.get(Q)??Promise.resolve(),V,X=new Promise((H)=>{V=H}),z=Y.catch(()=>{}).then(()=>X);d8.set(Q,z),await Y.catch(()=>{});try{return await Z()}finally{if(V(),d8.get(Q)===z)d8.delete(Q)}}function _2($){let Z=$.trim();if(!_F.test(Z))return null;return Z}function a8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function D4($,Z){return`${$}[${Z}]`}function nz($){return`${q4}${$}`}function F4($,Z,J){return iz(BF($),D4(Z,J))}function az($,Z,J){let Q=LF($,Z,J);if(!Q)return null;let Y=WF(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function oz($,Z){MZ($);let J=b0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${q4}`]).split(`
99
+ `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(q4)),Q=OZ($),Y=[];for(let V of J){let X=V.slice(q4.length);if(!_2(X))continue;let z=D4(Z,X),H=F4($,Z,X),G=Q.get(V)??null,W=!!G&&x1(G),K=ez($,V,W),j={slug:X,chatName:z,branch:V,state:K,expectedPath:H,worktreePath:W?G:null,mounted:W,dirtyCount:null,statusLine:null,error:null};if(G&&x1(G))try{let D=b0(G,["status","--porcelain=v1","--branch"]).split(`
100
+ `).filter(Boolean);j.statusLine=D[0]?.startsWith("## ")?D[0].slice(3):null,j.dirtyCount=D.filter((P)=>!P.startsWith("## ")).length}catch(_){j.error=NZ(_)}Y.push(j)}return Y.sort((V,X)=>V.slug.localeCompare(X.slug))}function sz($,Z,J){let Q=_2(J);if(!Q)throw Error(`invalid worktree name "${J}"`);MZ($);let Y=nz(Q),V=D4(Z,Q),X=F4($,Z,Q),z=FF($,Y),H=OZ($).get(Y)??null,G=z&&!H&&ez($,Y,!1)==="merged"?b0($,["rev-parse","HEAD"]).trim():null;if(H){if(!AZ(H,X))throw Error(`branch ${Y} is already mounted at ${H}`);return rz(X,Y),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(x1(X)){if(!KF(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!z)throw Error(`${X} already exists while branch ${Y} does not`)}if(z){if(b0($,["worktree","add",X,Y]),G)b0(X,["rebase",G]);return{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return b0($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function tz($,Z,J){let Q=UZ($,Z,J);if(!x1(Q.worktreePath))return Q;return b0($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function UZ($,Z,J){let Q=_2(J);if(!Q)throw Error(`invalid worktree name "${J}"`);MZ($);let Y=nz(Q),V=D4(Z,Q),X=F4($,Z,Q),z=OZ($).get(Y)??null;if(z&&!AZ(z,X))throw Error(`branch ${Y} is already mounted at ${z}, outside managed path ${X}`);let H=z??X;if(!x1(H))return{slug:Q,chatName:V,branch:Y,worktreePath:H,removedWorktree:!1};if(!z)throw Error(`${H} is not a registered worktree of ${$}`);rz(H,Y);let G=b0(H,["status","--porcelain=v1"]).split(`
100
101
  `).filter(Boolean);if(G.length>0){let W=G.slice(0,8).join(`
101
102
  `);throw Error(`worktree has uncommitted changes:
102
- ${W}`)}return{slug:Q,chatName:V,branch:Y,worktreePath:H,removedWorktree:!1}}function UZ($){if(!x1($))throw Error(`project directory does not exist: ${$}`);let Z=b0($,["rev-parse","--show-toplevel"]).trim();if(d8(Z)!==d8($))throw Error(`${$} is not the git repository root (${Z})`)}function dz($,Z){let J=b0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function ZF($,Z,J){let Q=JF($);if(!Q?.startsWith(q4))return null;let Y=Q.slice(q4.length);if(!j2(Y))throw Error(`invalid worktree branch "${Q}"`);let V=F4(Z,J,Y);if(!OZ($,V))return null;let X=YF($,QF(Y));return X?{path:X,slug:Y}:null}function JF($){if(!x1($))return null;try{return b0($,["branch","--show-current"]).trim()||null}catch(Z){if(XF(Z))return null;throw Z}}function QF($){return $.split("-",1)[0]??$}function YF($,Z){let J=`agents.${Z}.md`.toLowerCase(),Q=oD($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?gz($,Q[0]):null}function VF($,Z){try{return b0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function iz($,Z,J){let Q=b0($,["rev-parse",Z]).trim(),Y=b0($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(Iz($,Z,"HEAD"))return"merged";if(Iz($,"HEAD",Z))return"active";return"stale"}function Iz($,Z,J){try{return b0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function MZ($){let Z=new Map,J=b0($,["worktree","list","--porcelain","-z"]),Q="";for(let Y of J.split("\x00")){if(!Y)Q="";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 OZ($,Z){let J=(Q)=>{let Y=x1(Q)?d8(Q):eD(Q);return process.platform==="win32"?Y.toLowerCase():Y};return J($)===J(Z)}function b0($,Z){try{return aD("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(AZ(J))}}function AZ($){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 XF($){return/not a git repository/i.test(AZ($))}var q4="work/",$F,u8;var NZ=N(()=>{$F=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,u8=new Map});import{lstatSync as HF,realpathSync as GF,statSync as WF}from"node:fs";import{basename as KF,dirname as nz,isAbsolute as BF,join as az,resolve as jF}from"node:path";function RZ($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function TZ($,Z,J){let Q=RZ($),Y=n8(Q),V=J[Y]?.cwd?.trim()||az(Z,Y);if(Q===Y)return V;return F4(V,Y,Q.slice(Y.length+1,-1))}function Q$($){if(!BF($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=oz(jF($));return process.platform==="win32"?Z.toLowerCase():Z}function oz($){try{let Z=GF($);if(!WF(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||nz($)===$)throw Z;try{if(HF($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return az(oz(nz($)),KF($))}}function sz($,Z,J){let Q=Q$($),Y,V=new Map;for(let[X,z]of Object.entries(J)){if(Q$(TZ(X,Z,J))!==Q)continue;Y??={cwd:$};for(let H of["settingSources","strictMcp","tools","loadProjectMcp"]){let G=z[H];if(G===void 0)continue;if(Y[H]!==void 0&&Y[H]!==G)throw Error(`同一工作目录的项目配置冲突: ${V.get(H)} / ${X}, ${H} (${$})`);Object.assign(Y,{[H]:G}),V.set(H,X)}}return Y}var U4=N(()=>{NZ()});function _F($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function EZ($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let z=J.exec($);if(!z)break;let H=z[1],G=new RegExp(`^(?: {0,3})${_F(H[0])}{${H.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=z.index+z[0].length;let W=G.exec($),K=W?W.index+W[0].length:$.length;Z.push({start:z.index,end:K}),Q=K}let Y=[...Z],V=[],X=0;for(let z of Z){if(X<z.start)V.push({start:X,end:z.start});X=z.end}if(X<$.length)V.push({start:X,end:$.length});for(let z of V){let H=$.slice(z.start,z.end),G=/(`+)[^\n]*?\1/g,W;while((W=G.exec(H))!==null)Y.push({start:z.start+W.index,end:z.start+W.index+W[0].length})}return Y.sort((z,H)=>z.start-H.start)}function xZ($,Z){if(!$)return $;let J=EZ($);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 PF($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function tz($){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 S1($){if(Array.isArray($))return $.map((Q)=>S1(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=S1(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=SZ(Z.content);return J}function J0($){return xZ($,(Z)=>LF(tz(PF(Z))))}function LF($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
103
+ ${W}`)}return{slug:Q,chatName:V,branch:Y,worktreePath:H,removedWorktree:!1}}function MZ($){if(!x1($))throw Error(`project directory does not exist: ${$}`);let Z=b0($,["rev-parse","--show-toplevel"]).trim();if(i8(Z)!==i8($))throw Error(`${$} is not the git repository root (${Z})`)}function rz($,Z){let J=b0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function LF($,Z,J){let Q=PF($);if(!Q?.startsWith(q4))return null;let Y=Q.slice(q4.length);if(!_2(Y))throw Error(`invalid worktree branch "${Q}"`);let V=F4(Z,J,Y);if(!AZ($,V))return null;let X=DF($,qF(Y));return X?{path:X,slug:Y}:null}function PF($){if(!x1($))return null;try{return b0($,["branch","--show-current"]).trim()||null}catch(Z){if(UF(Z))return null;throw Z}}function qF($){return $.split("-",1)[0]??$}function DF($,Z){let J=`agents.${Z}.md`.toLowerCase(),Q=GF($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?iz($,Q[0]):null}function FF($,Z){try{return b0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function ez($,Z,J){let Q=b0($,["rev-parse",Z]).trim(),Y=b0($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(dz($,Z,"HEAD"))return"merged";if(dz($,"HEAD",Z))return"active";return"stale"}function dz($,Z,J){try{return b0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function OZ($){let Z=new Map,J=b0($,["worktree","list","--porcelain","-z"]),Q="";for(let Y of J.split("\x00")){if(!Y)Q="";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 AZ($,Z){let J=(Q)=>{let Y=x1(Q)?i8(Q):jF(Q);return process.platform==="win32"?Y.toLowerCase():Y};return J($)===J(Z)}function b0($,Z){try{return HF("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(NZ(J))}}function NZ($){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 UF($){return/not a git repository/i.test(NZ($))}var q4="work/",_F,d8;var RZ=R(()=>{_F=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,d8=new Map});import{lstatSync as OF,realpathSync as AF,statSync as NF}from"node:fs";import{basename as RF,dirname as $H,isAbsolute as TF,join as ZH,resolve as EF}from"node:path";function TZ($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function EZ($,Z,J){let Q=TZ($),Y=a8(Q),V=J[Y]?.cwd?.trim()||ZH(Z,Y);if(Q===Y)return V;return F4(V,Y,Q.slice(Y.length+1,-1))}function Q$($){if(!TF($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=JH(EF($));return process.platform==="win32"?Z.toLowerCase():Z}function JH($){try{let Z=AF($);if(!NF(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||$H($)===$)throw Z;try{if(OF($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return ZH(JH($H($)),RF($))}}function QH($,Z,J){let Q=Q$($),Y,V=new Map;for(let[X,z]of Object.entries(J)){if(Q$(EZ(X,Z,J))!==Q)continue;Y??={cwd:$};for(let H of["settingSources","strictMcp","tools","loadProjectMcp"]){let G=z[H];if(G===void 0)continue;if(Y[H]!==void 0&&Y[H]!==G)throw Error(`同一工作目录的项目配置冲突: ${V.get(H)} / ${X}, ${H} (${$})`);Object.assign(Y,{[H]:G}),V.set(H,X)}}return Y}var U4=R(()=>{RZ()});function xF($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function xZ($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let z=J.exec($);if(!z)break;let H=z[1],G=new RegExp(`^(?: {0,3})${xF(H[0])}{${H.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=z.index+z[0].length;let W=G.exec($),K=W?W.index+W[0].length:$.length;Z.push({start:z.index,end:K}),Q=K}let Y=[...Z],V=[],X=0;for(let z of Z){if(X<z.start)V.push({start:X,end:z.start});X=z.end}if(X<$.length)V.push({start:X,end:$.length});for(let z of V){let H=$.slice(z.start,z.end),G=/(`+)[^\n]*?\1/g,W;while((W=G.exec(H))!==null)Y.push({start:z.start+W.index,end:z.start+W.index+W[0].length})}return Y.sort((z,H)=>z.start-H.start)}function SZ($,Z){if(!$)return $;let J=xZ($);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 SF($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function YH($){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 S1($){if(Array.isArray($))return $.map((Q)=>S1(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=S1(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=CZ(Z.content);return J}function Q0($){return SZ($,(Z)=>CF(YH(SF(Z))))}function CF($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
103
104
  \`\`\`
104
105
  ${J.trim()}
105
106
  \`\`\`
@@ -107,214 +108,214 @@ ${J.trim()}
107
108
  \`\`\`
108
109
  ${J.trim()}
109
110
  \`\`\`
110
- `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function SZ($){return xZ($,tz)}var b;var h0=N(()=>{b={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"}});async function CZ($){let Z=await wZ("feishu chat.get",()=>K0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)a8("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 bZ($,Z){let J=await wZ("feishu tasklist.create",()=>K0.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)a8("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 kZ($){let Z=await wZ("feishu tasklist.delete",()=>K0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)a8("feishu tasklist.delete",Z)}function rz($,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.error?.permission_violations??Q.permission_violations??J.error?.permission_violations,V=Array.isArray(Y)?Y.map((X)=>X?.scope??X?.subject??X?.name??X).filter(Boolean).join(", "):"";return`${$} failed ${v(Z)}${V?` missing_scopes=${V}`:""}`}async function wZ($,Z){try{return await Z()}catch(J){a8($,J)}}function a8($,Z){throw Error(rz($,Z))}var ez=N(()=>{$0()});var Z0={};r$(Z0,{writeAliveMarker:()=>rZ,urgentApp:()=>L2,uploadImageKey:()=>XJ,uploadAndSend:()=>l9,updateCard:()=>E4,unbindSessionChat:()=>s8,tempProjectName:()=>X1,tempChatName:()=>aZ,setPendingConversationLaunchChecked:()=>k1,sendTextRaw:()=>I,sendText:()=>k,sendImage:()=>X7,sendFile:()=>UH,sendCard:()=>i,sanitizeSessionName:()=>HJ,resolveProjectDir:()=>O4,replaceTurnAnchors:()=>V$,registerTempSessionLease:()=>pZ,refreshChatList:()=>p9,readAliveMarker:()=>eZ,provisionProject:()=>zJ,projectProfileForDirectory:()=>I9,projectProfile:()=>MF,preferredChatForSession:()=>P0,loadTempSessionLeases:()=>mZ,loadSessionTurnsMap:()=>iZ,loadSessionResumeMap:()=>uZ,loadSessionModelMap:()=>oZ,loadSessionChatMap:()=>lZ,listNormalChatIdsByName:()=>J7,isOpenAIChatGPTAuthenticated:()=>u9,hasTempSessionLease:()=>cZ,getTurnAnchors:()=>N4,getTenantToken:()=>m$,getSessionResumeRef:()=>b1,getSessionModelSelection:()=>sZ,getSessionBranchBase:()=>R4,getPendingConversationLaunch:()=>T4,getChatTailMessageId:()=>VJ,formatFeishuApiError:()=>rz,findNormalChatIdByName:()=>Q7,fetchChatOwnerOpenId:()=>CZ,fetchChatName:()=>YJ,ensureChatForSession:()=>$J,downloadAttachment:()=>c9,disbandChatForSessionExact:()=>QJ,disbandChatForSession:()=>JJ,deleteTasklistByGuid:()=>kZ,deleteReaction:()=>g0,createTempChatForSession:()=>ZJ,createTasklistWithOwner:()=>bZ,client:()=>K0,clearSessionResumeChecked:()=>A4,clearSessionConversationState:()=>tZ,chatNameCache:()=>L0,chatIdForSession:()=>Z7,bindSessionToChat:()=>M4,bindSessionResumeChecked:()=>m9,bindSessionModelChecked:()=>w1,bindSessionModel:()=>xF,appendTurnAnchorChecked:()=>nZ,addReaction:()=>X$,PROJECTS_ROOT:()=>gZ,MAX_UPLOAD_BYTES:()=>V7});import*as e8 from"@larksuiteoapi/node-sdk";import{execSync as qF}from"node:child_process";import{randomUUID as $7}from"node:crypto";import{mkdirSync as yZ,readFileSync as P2,statSync as XH,writeFileSync as zH}from"node:fs";import{readFile as DF}from"node:fs/promises";import{homedir as $H}from"node:os";import{basename as _2,extname as FF,isAbsolute as HH,join as fZ}from"node:path";import{sync as UF}from"cross-spawn";function hZ(){let $={};for(let[Z,J]of Y$)$[Z]=J;a($5,$)}function mZ(){Y$.clear();try{let $=JSON.parse(P2($5,"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"||!X1(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}Y$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}B(`feishu: loaded ${Y$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function pZ($,Z){if(!X1($))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 Y$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=Y$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};Y$.set(Z,Q);try{hZ()}catch(Y){if(J)Y$.set(Z,J);else Y$.delete(Z);throw Y}}function cZ($,Z){let J=Y$.get(Z);return J?.sessionName===$&&J.chatId===Z}function MF($){return m.projects[$]}function O4($){return TZ($,gZ,m.projects)}function I9($){return sz($,gZ,m.projects)}function n0($,Z){let J=A$(Z);return new y0(`${$} failed ${v(Z)}`,J.status,J.code,J.retryAfter,J.logId,J.message)}function g9($,Z={}){return V0($,{...Z,signal:Z.signal??AbortSignal.timeout(KH)})}async function BH($,Z,J){let Q=Z.signal??AbortSignal.timeout(KH);try{return await B$(await g9($,{...Z,signal:Q}),J)}catch(Y){if(Q.aborted&&Q.reason?.name==="TimeoutError")throw Q.reason;throw Y}}async function m$(){if(o8&&Date.now()<ZH)return o8;return vZ??=(async()=>{let $=await BH("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:GH,app_secret:WH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return o8=$.tenant_access_token,ZH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,o8})().finally(()=>{vZ=null}),vZ}function lZ(){try{let $=JSON.parse(P2(s6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")P0.set(Z,J);B(`feishu: loaded ${P0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function jH(){try{IZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function IZ(){let $={};for(let[Z,J]of P0)$[Z]=J;a(s6,$)}function M4($,Z){if(P0.get($)===Z)return;let J=P0.get($);P0.set($,Z),jH(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function s8($){let Z=P0.get($);if(!Z)return;P0.delete($),jH(),B(`feishu: unbound session "${$}" from ${Z}`)}function f9($,Z){let J=A0.get($)??{};J[Z.provider]=Z,A0.set($,J)}function JH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=g$(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"||!HH(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function QH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!g$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!HH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function AF($,Z,J){if(typeof $!=="string")return QH($);if(!Z)throw Error("cannot bind a conversation without a provider");return QH({provider:Z,sessionId:$,cwd:J??null})}function uZ(){try{let $=JSON.parse(P2(t6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");A0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){f9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=JH(Q);if(Y){f9(Z,Y);continue}for(let V of YZ){let X=Q[V];if(typeof X==="string"&&X.trim()){f9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let z=JH(X,V);if(z)f9(Z,z)}}B(`feishu: loaded ${A0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function t8(){let $={};for(let[Z,J]of A0){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}a(t6,$)}function m9($,Z,J,Q){let Y=AF(Z,J,Q),V=A0.get($),X=V?{...V}:void 0,z=V?.[Y.provider];if(z?.sessionId===Y.sessionId&&z.cwd===Y.cwd)return;f9($,Y);try{t8()}catch(H){if(X)A0.set($,X);else A0.delete($);throw H}}function b1($,Z="codex"){let J=A0.get($)?.[Z];return J?{...J}:null}function A4($,Z){let J=A0.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)A0.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)A0.delete($);else A0.set($,Y)}try{t8()}catch(Y){throw A0.set($,Q),Y}}function _H($){if(!$||typeof $!=="object")return null;let Z=$;if(!g$(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 PH($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=_H(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 LH($){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=_H(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=PH(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{M0(Q,J.provider)}catch{return null}return Q}function NF($){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 Q=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Y=PH(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:NF(J.writes)}}function TF($){if(!$||typeof $!=="object")return null;let Z=$,J=LH(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 dZ($){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 iZ(){try{let $=JSON.parse(P2(r6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");Q0.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let V,X,z=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 j=LH(K.base);if(!j){J++;continue}X=j}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let j=TF(K.pendingLaunch);if(!j){J++;continue}z=j}}else{J++;continue}let H=A0.get(Q),G=H?.claude!==void 0&&H.codex===void 0?"claude":null,W=[];for(let K of V){let j=RF(K,G);if(j)W.push(j);else J++}if(W.length||X!==null||z)Q0.set(Q,{base:X,anchors:W,...z?{pendingLaunch:z}:{}}),Z+=W.length}if(B(`feishu: loaded ${Z} turn anchors across ${Q0.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 h9(){let $={};for(let[Z,J]of Q0)$[Z]=J;a(r6,$)}function nZ($,Z){let J=Q0.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>YH){let V=Q.splice(0,Q.length-YH),X=V[V.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}Q0.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{h9()}catch(V){if(J)Q0.set($,J);else Q0.delete($);throw V}}function N4($){return Q0.get($)?.anchors??[]}function R4($){return Q0.get($)?.base??null}function T4($){let Z=Q0.get($)?.pendingLaunch;return Z?dZ(Z):null}function k1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");M0(Z.launch,"claude",Z.launch.source.cwd)}let J=Q0.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)Q0.delete($);else Q0.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:dZ(Z)}:{}});try{h9()}catch(V){if(J)Q0.set($,J);else Q0.delete($);throw V}}function V$($,Z,J,Q){let Y=Q0.get($),V=Q===void 0?Y?.pendingLaunch:Q??void 0,X=V?dZ(V):void 0;if(Z.length===0&&J===null&&!X)Q0.delete($);else Q0.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{h9()}catch(z){if(Y)Q0.set($,Y);else Q0.delete($);throw z}}function X1($){return VH.test($)?$.replace(VH,""):null}function aZ($,Z=[]){let J=new Date,Q=(z)=>String(z).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,V=new Set([...L0.values(),...Q0.keys(),...Z]),X=`${$}*${Y}`;for(let z=2;V.has(X);z++)X=`${$}*${Y}-${z}`;return X}function oZ(){try{let $=JSON.parse(P2(e6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){I0.set(Z,{provider:W4(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,V=g$(Y)?Y:typeof Q==="string"&&Q.trim()?W4(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(V==="claude"&&!X)continue;let{effort:z,tokenSourceId:H}=J,G=typeof H==="string"&&H.trim()?H.trim():null,W=V==="dsh"?O0(z)?z:null:V==="claude"?R0(z)?z:null:_$(z)?z:null;I0.set(Z,{provider:V,model:X,effort:W,...G?{tokenSourceId:G}:{}})}B(`feishu: loaded ${I0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-model-map failed: ${$?.message??$}`)}}function EF(){try{r8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function r8(){let $={};for(let[Z,J]of I0)$[Z]=J;a(e6,$)}function xF($,Z,J,Q,Y){let V=I0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Q&&(V.tokenSourceId??null)===(Y??null))return;I0.set($,{provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}}),EF()}function w1($,Z,J,Q,Y){let V=I0.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;I0.set($,X);try{r8()}catch(z){if(V)I0.set($,V);else I0.delete($);throw z}}function sZ($){let Z=I0.get($);if(Z)return Z;let J=X1($);return J?I0.get(J)??null:null}function tZ($){let Z=P0.get($),J=A0.get($),Q=I0.get($),Y=Q0.get($),V=[...Y$.entries()].filter(([,X])=>X.sessionName===$);P0.delete($),A0.delete($),I0.delete($),Q0.delete($);for(let[X]of V)Y$.delete(X);try{IZ(),t8(),r8(),h9(),hZ()}catch(X){if(Z)P0.set($,Z);if(J)A0.set($,J);if(Q)I0.set($,Q);if(Y)Q0.set($,Y);for(let[H,G]of V)Y$.set(H,G);let z=[X];for(let H of[IZ,t8,r8,h9,hZ])try{H()}catch(G){z.push(G)}throw z.length===1?z[0]:AggregateError(z,`failed to clear and restore conversation state for ${$}`)}}function rZ($){a(J5,$)}function eZ(){let $;try{$=P2(J5,"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 Z7($){let Z=P0.get($);if(Z){let Q=L0.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 L0)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 p9(){try{let $;do{let Z=await K0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});if(Z.code&&Z.code!==0)throw n0("feishu chat.list",Z);for(let J of Z.data?.items??[])if(J.chat_id&&J.name)L0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${L0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function J7(){let $=new Map,Z;do{let J=await K0.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw n0("feishu chat.list",J);for(let Q of J.data?.items??[]){if(!Q.chat_id||!Q.name)continue;if(Q.chat_status&&Q.chat_status!=="normal")continue;L0.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 Q7($){let Z=P0.get($);if(Z&&L0.get(Z)===$){let V=await qH(Z);if(V.name===$&&DH(V.status))return Z;L0.delete(Z),s8($)}let Q=(await J7()).get($)??[];if(Q.length===0)return null;let Y=P0.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 $J($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await Q7($);if(J){let V=await SF(J,Z);return M4($,J),{chatId:J,created:!1,joined:V}}let Q=await K0.im.chat.create({params:{user_id_type:"open_id",uuid:$7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw n0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return L0.set(Y,$),M4($,Y),{chatId:Y,created:!0,joined:!0}}async function ZJ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await Q7($))throw Error(`temporary group name already exists: ${$}`);let Q=await K0.im.chat.create({params:{user_id_type:"open_id",uuid:$7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw n0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return L0.set(Y,$),M4($,Y),{chatId:Y,created:!0,joined:!0}}async function JJ($){let Z=await Q7($);if(!Z)return s8($),{chatId:null,disbanded:!1};let J=await K0.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw n0("feishu chat.delete",J);if(L0.delete(Z),P0.get($)===Z)s8($);return{chatId:Z,disbanded:!0}}async function QJ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await qH(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!DH(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await K0.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw n0("feishu chat.delete",Q);return L0.delete(Z),{chatId:Z,disbanded:!0}}async function SF($,Z){let J;do{let Y=await K0.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 n0("feishu chatMembers.get",Y);for(let V of Y.data?.items??[])if(V.member_id===Z)return!1;J=Y.data?.page_token}while(J);let Q=await K0.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw n0("feishu chatMembers.create",Q);return!0}async function YJ($){try{let Z=await m$(),J=await g9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}}),Y=(await B$(J,`fetchChatName ${$}`)).data?.name;if(typeof Y==="string"&&Y)return L0.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 Y7($,Z,J,Q,Y){let V=$7();try{return await s1(`send${$} chat=${Z}`,async()=>{let X=await K0.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Q,uuid:V}});if(X?.code!==0)throw n0(`send${$}`,X);let z=X?.data?.message_id;if(typeof z!=="string"||!z.trim())throw Error(`send${$} message_id MISS`);return z})}catch(X){return Y?.(X),null}}async function qH($){let Z=await K0.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw n0("feishu chat.get",Z);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function DH($){return $===null||$==="normal"}async function k($,Z,J){return R$($,()=>Y7("Text",$,"text",JSON.stringify({text:Z}),J))}async function i($,Z,J){return R$($,()=>Y7("Card",$,"interactive",JSON.stringify(S1(Z)),J))}async function VJ($){let Z=await K0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw n0("feishu message.list",Z);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 E4($,Z){let J=await K0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(S1(Z))}});if(J?.code!==0)throw n0("feishu message.patch",J)}async function I($,Z){return R$($,()=>CF($,Z))}async function CF($,Z){try{let J=await m$(),Q=await g9("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})})});return(await B$(Q,`sendTextRaw chat=${$}`)).data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function X$($,Z){if(!$)return null;try{let J=await K0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}});if(J?.code&&J.code!==0)throw n0("feishu messageReaction.create",J);return J?.data?.reaction_id??null}catch(J){return B(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function g0($,Z){if(!$||!Z)return;try{let J=await K0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}});if(J?.code&&J.code!==0)throw n0("feishu messageReaction.delete",J)}catch(J){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function L2($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await m$(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let Y=await g9(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})}),X=(await B$(Y,`urgentApp ${$}`)).data?.invalid_user_id_list??[],z=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${z}${X.length?` invalid=${X.length}`:""}`)}catch(Y){B(`feishu: urgentApp ${$} failed: ${Y}`)}}async function c9($,Z,J,Q){try{let Y=await m$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await g9(V,{headers:{Authorization:`Bearer ${Y}`}});if(!X.ok)await B$(X,`download ${J}`);let z=Buffer.from(await X.arrayBuffer());yZ(Q5,{recursive:!0});let H=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=fZ(Q5,`${Date.now()}-${$7()}-${H}`);return zH(G,z,{flag:"wx"}),B(`feishu: downloaded ${J} ${G} (${z.length}B)`),G}catch(Y){B(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function kF($){return bF.has(FF($).toLowerCase())}async function FH($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Q;return s1(`${J} ${$}`,async()=>{if(Q??=new Blob([Uint8Array.from(await DF($))]),Q.size>V7)throw Error(`${_2($)} 超过 30 MB`);let Y=await m$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",_2($));V.append(Z,Q,_2($));let z=(await BH(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:V},J)).data?.[`${Z}_key`];if(typeof z!=="string"||!z.trim())throw Error(`${J} ${Z}_key MISS`);return z})}async function XJ($,Z){try{let J=XH($);if(!J.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),Z?.(Error("路径不是普通文件")),null;if(J.size>V7)return B(`feishu: uploadImageKey oversize — ${$} (${(J.size/1024/1024).toFixed(1)} MB)`),Z?.(Error(`${_2($)} 超过 30 MB`)),null}catch(J){return B(`feishu: uploadImageKey stat failed — ${$}: ${J}`),Z?.(J),null}try{return await FH($,"image")}catch(J){return Z?.(J),null}}async function X7($,Z,J){return R$($,()=>Y7("Image",$,"image",JSON.stringify({image_key:Z}),J))}async function UH($,Z,J){return R$($,()=>Y7("File",$,"file",JSON.stringify({file_key:Z}),J))}async function l9($,Z){try{let Y=XH(Z);if(!Y.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await k($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>V7)return B(`feishu: uploadAndSend oversize — ${Z} (${Y.size}B)`),await k($,`❌ 出站文件: ${_2(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return B(`feishu: uploadAndSend stat failed — ${Z}: ${Y}`),await k($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=kF(Z)?"image":"file",Q=J==="image"?"出站图片":"出站文件";try{let Y=await FH(Z,J),V,X=(H)=>{V=H},z=await(J==="image"?X7($,Y,X):UH($,Y,X));if(!z)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await k($,`❌ ${Q}发送失败: ${_2(Z)}(上传已完成)
111
- ${v(V)}`),!1;return B(`feishu: uploadAndSend ${Z} delivered msg=${z}`),!0}catch(Y){return B(`feishu: uploadAndSend ${Z} failed: ${Y}`),await k($,`❌ ${Q}上传失败: ${_2(Z)} — ${v(Y)}`),!1}}function zJ($){yZ($,{recursive:!0}),B(`feishu: provisioned ${$}`);let Z=fZ($H(),".codex","config.toml");try{yZ(fZ($H(),".codex"),{recursive:!0});let J="";try{J=P2(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
111
+ `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function CZ($){return SZ($,YH)}var C;var h0=R(()=>{C={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"}});async function bZ($){let Z=await vZ("feishu chat.get",()=>K0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)o8("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 kZ($,Z){let J=await vZ("feishu tasklist.create",()=>K0.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)o8("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 wZ($){let Z=await vZ("feishu tasklist.delete",()=>K0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)o8("feishu tasklist.delete",Z)}function VH($,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.error?.permission_violations??Q.permission_violations??J.error?.permission_violations,V=Array.isArray(Y)?Y.map((X)=>X?.scope??X?.subject??X?.name??X).filter(Boolean).join(", "):"";return`${$} failed ${w(Z)}${V?` missing_scopes=${V}`:""}`}async function vZ($,Z){try{return await Z()}catch(J){o8($,J)}}function o8($,Z){throw Error(VH($,Z))}var XH=R(()=>{$0()});var Z0={};r$(Z0,{writeAliveMarker:()=>eZ,urgentApp:()=>q2,uploadImageKey:()=>zJ,uploadAndSend:()=>u9,updateCard:()=>E4,unbindSessionChat:()=>t8,tempProjectName:()=>X1,tempChatName:()=>oZ,setPendingConversationLaunchChecked:()=>k1,sendTextRaw:()=>I,sendText:()=>b,sendImage:()=>z7,sendFile:()=>EH,sendCard:()=>n,sanitizeSessionName:()=>GJ,resolveProjectDir:()=>O4,replaceTurnAnchors:()=>V$,registerTempSessionLease:()=>cZ,refreshChatList:()=>c9,readAliveMarker:()=>$J,provisionProject:()=>HJ,projectProfileForDirectory:()=>g9,projectProfile:()=>yF,preferredChatForSession:()=>L0,loadTempSessionLeases:()=>pZ,loadSessionTurnsMap:()=>nZ,loadSessionResumeMap:()=>dZ,loadSessionModelMap:()=>sZ,loadSessionChatMap:()=>uZ,listNormalChatIdsByName:()=>Q7,isOpenAIChatGPTAuthenticated:()=>d9,hasTempSessionLease:()=>lZ,getTurnAnchors:()=>N4,getTenantToken:()=>m$,getSessionResumeRef:()=>b1,getSessionModelSelection:()=>tZ,getSessionBranchBase:()=>R4,getPendingConversationLaunch:()=>T4,getChatTailMessageId:()=>XJ,formatFeishuApiError:()=>VH,findNormalChatIdByName:()=>Y7,fetchChatOwnerOpenId:()=>bZ,fetchChatName:()=>VJ,ensureChatForSession:()=>ZJ,downloadAttachment:()=>l9,disbandChatForSessionExact:()=>YJ,disbandChatForSession:()=>QJ,deleteTasklistByGuid:()=>wZ,deleteReaction:()=>g0,createTempChatForSession:()=>JJ,createTasklistWithOwner:()=>kZ,client:()=>K0,clearSessionResumeChecked:()=>A4,clearSessionConversationState:()=>rZ,chatNameCache:()=>P0,chatIdForSession:()=>J7,bindSessionToChat:()=>M4,bindSessionResumeChecked:()=>p9,bindSessionModelChecked:()=>w1,bindSessionModel:()=>cF,appendTurnAnchorChecked:()=>aZ,addReaction:()=>X$,PROJECTS_ROOT:()=>mZ,MAX_UPLOAD_BYTES:()=>X7});import*as $7 from"@larksuiteoapi/node-sdk";import{execSync as bF}from"node:child_process";import{randomUUID as Z7}from"node:crypto";import{mkdirSync as fZ,readFileSync as P2,statSync as jH,writeFileSync as _H}from"node:fs";import{readFile as kF}from"node:fs/promises";import{homedir as zH}from"node:os";import{basename as L2,extname as wF,isAbsolute as LH,join as hZ}from"node:path";import{sync as vF}from"cross-spawn";function IZ(){let $={};for(let[Z,J]of Y$)$[Z]=J;a(Z5,$)}function pZ(){Y$.clear();try{let $=JSON.parse(P2(Z5,"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"||!X1(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}Y$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}B(`feishu: loaded ${Y$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function cZ($,Z){if(!X1($))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 Y$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=Y$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};Y$.set(Z,Q);try{IZ()}catch(Y){if(J)Y$.set(Z,J);else Y$.delete(Z);throw Y}}function lZ($,Z){let J=Y$.get(Z);return J?.sessionName===$&&J.chatId===Z}function yF($){return m.projects[$]}function O4($){return EZ($,mZ,m.projects)}function g9($){return QH($,mZ,m.projects)}function n0($,Z){let J=A$(Z);return new y0(`${$} failed ${w(Z)}`,J.status,J.code,J.retryAfter,J.logId,J.message)}function m9($,Z={}){return X0($,{...Z,signal:Z.signal??AbortSignal.timeout(DH)})}async function FH($,Z,J){let Q=Z.signal??AbortSignal.timeout(DH);try{return await B$(await m9($,{...Z,signal:Q}),J)}catch(Y){if(Q.aborted&&Q.reason?.name==="TimeoutError")throw Q.reason;throw Y}}async function m$(){if(s8&&Date.now()<HH)return s8;return yZ??=(async()=>{let $=await FH("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:PH,app_secret:qH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return s8=$.tenant_access_token,HH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,s8})().finally(()=>{yZ=null}),yZ}function uZ(){try{let $=JSON.parse(P2(t6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")L0.set(Z,J);B(`feishu: loaded ${L0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function UH(){try{gZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function gZ(){let $={};for(let[Z,J]of L0)$[Z]=J;a(t6,$)}function M4($,Z){if(L0.get($)===Z)return;let J=L0.get($);L0.set($,Z),UH(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function t8($){let Z=L0.get($);if(!Z)return;L0.delete($),UH(),B(`feishu: unbound session "${$}" from ${Z}`)}function h9($,Z){let J=A0.get($)??{};J[Z.provider]=Z,A0.set($,J)}function GH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=g$(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"||!LH(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function WH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!g$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!LH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function hF($,Z,J){if(typeof $!=="string")return WH($);if(!Z)throw Error("cannot bind a conversation without a provider");return WH({provider:Z,sessionId:$,cwd:J??null})}function dZ(){try{let $=JSON.parse(P2(r6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");A0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){h9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=GH(Q);if(Y){h9(Z,Y);continue}for(let V of VZ){let X=Q[V];if(typeof X==="string"&&X.trim()){h9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let z=GH(X,V);if(z)h9(Z,z)}}B(`feishu: loaded ${A0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function r8(){let $={};for(let[Z,J]of A0){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}a(r6,$)}function p9($,Z,J,Q){let Y=hF(Z,J,Q),V=A0.get($),X=V?{...V}:void 0,z=V?.[Y.provider];if(z?.sessionId===Y.sessionId&&z.cwd===Y.cwd)return;h9($,Y);try{r8()}catch(H){if(X)A0.set($,X);else A0.delete($);throw H}}function b1($,Z="codex"){let J=A0.get($)?.[Z];return J?{...J}:null}function A4($,Z){let J=A0.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)A0.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)A0.delete($);else A0.set($,Y)}try{r8()}catch(Y){throw A0.set($,Q),Y}}function MH($){if(!$||typeof $!=="object")return null;let Z=$;if(!g$(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 OH($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=MH(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 AH($){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=MH(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=OH(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{M0(Q,J.provider)}catch{return null}return Q}function IF($){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 gF($,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=OH(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:IF(J.writes)}}function mF($){if(!$||typeof $!=="object")return null;let Z=$,J=AH(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 iZ($){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 nZ(){try{let $=JSON.parse(P2(e6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");Y0.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let V,X,z=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 j=AH(K.base);if(!j){J++;continue}X=j}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let j=mF(K.pendingLaunch);if(!j){J++;continue}z=j}}else{J++;continue}let H=A0.get(Q),G=H?.claude!==void 0&&H.codex===void 0?"claude":null,W=[];for(let K of V){let j=gF(K,G);if(j)W.push(j);else J++}if(W.length||X!==null||z)Y0.set(Q,{base:X,anchors:W,...z?{pendingLaunch:z}:{}}),Z+=W.length}if(B(`feishu: loaded ${Z} turn anchors across ${Y0.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 I9(){let $={};for(let[Z,J]of Y0)$[Z]=J;a(e6,$)}function aZ($,Z){let J=Y0.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>KH){let V=Q.splice(0,Q.length-KH),X=V[V.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}Y0.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{I9()}catch(V){if(J)Y0.set($,J);else Y0.delete($);throw V}}function N4($){return Y0.get($)?.anchors??[]}function R4($){return Y0.get($)?.base??null}function T4($){let Z=Y0.get($)?.pendingLaunch;return Z?iZ(Z):null}function k1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");M0(Z.launch,"claude",Z.launch.source.cwd)}let J=Y0.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)Y0.delete($);else Y0.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:iZ(Z)}:{}});try{I9()}catch(V){if(J)Y0.set($,J);else Y0.delete($);throw V}}function V$($,Z,J,Q){let Y=Y0.get($),V=Q===void 0?Y?.pendingLaunch:Q??void 0,X=V?iZ(V):void 0;if(Z.length===0&&J===null&&!X)Y0.delete($);else Y0.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{I9()}catch(z){if(Y)Y0.set($,Y);else Y0.delete($);throw z}}function X1($){return BH.test($)?$.replace(BH,""):null}function oZ($,Z=[]){let J=new Date,Q=(z)=>String(z).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,V=new Set([...P0.values(),...Y0.keys(),...Z]),X=`${$}*${Y}`;for(let z=2;V.has(X);z++)X=`${$}*${Y}-${z}`;return X}function sZ(){try{let $=JSON.parse(P2($5,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){I0.set(Z,{provider:W4(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,V=g$(Y)?Y:typeof Q==="string"&&Q.trim()?W4(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(V==="claude"&&!X)continue;let{effort:z,tokenSourceId:H}=J,G=typeof H==="string"&&H.trim()?H.trim():null,W=V==="dsh"?O0(z)?z:null:V==="claude"?R0(z)?z:null:_$(z)?z:null;I0.set(Z,{provider:V,model:X,effort:W,...G?{tokenSourceId:G}:{}})}B(`feishu: loaded ${I0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-model-map failed: ${$?.message??$}`)}}function pF(){try{e8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function e8(){let $={};for(let[Z,J]of I0)$[Z]=J;a($5,$)}function cF($,Z,J,Q,Y){let V=I0.get($);if(V?.provider===Z&&V.model===J&&V.effort===Q&&(V.tokenSourceId??null)===(Y??null))return;I0.set($,{provider:Z,model:J,effort:Q,...Y?{tokenSourceId:Y}:{}}),pF()}function w1($,Z,J,Q,Y){let V=I0.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;I0.set($,X);try{e8()}catch(z){if(V)I0.set($,V);else I0.delete($);throw z}}function tZ($){let Z=I0.get($);if(Z)return Z;let J=X1($);return J?I0.get(J)??null:null}function rZ($){let Z=L0.get($),J=A0.get($),Q=I0.get($),Y=Y0.get($),V=[...Y$.entries()].filter(([,X])=>X.sessionName===$);L0.delete($),A0.delete($),I0.delete($),Y0.delete($);for(let[X]of V)Y$.delete(X);try{gZ(),r8(),e8(),I9(),IZ()}catch(X){if(Z)L0.set($,Z);if(J)A0.set($,J);if(Q)I0.set($,Q);if(Y)Y0.set($,Y);for(let[H,G]of V)Y$.set(H,G);let z=[X];for(let H of[gZ,r8,e8,I9,IZ])try{H()}catch(G){z.push(G)}throw z.length===1?z[0]:AggregateError(z,`failed to clear and restore conversation state for ${$}`)}}function eZ($){a(Q5,$)}function $J(){let $;try{$=P2(Q5,"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 J7($){let Z=L0.get($);if(Z){let Q=P0.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 P0)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 c9(){try{let $;do{let Z=await K0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});if(Z.code&&Z.code!==0)throw n0("feishu chat.list",Z);for(let J of Z.data?.items??[])if(J.chat_id&&J.name)P0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${P0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function Q7(){let $=new Map,Z;do{let J=await K0.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw n0("feishu chat.list",J);for(let Q of J.data?.items??[]){if(!Q.chat_id||!Q.name)continue;if(Q.chat_status&&Q.chat_status!=="normal")continue;P0.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 Y7($){let Z=L0.get($);if(Z&&P0.get(Z)===$){let V=await NH(Z);if(V.name===$&&RH(V.status))return Z;P0.delete(Z),t8($)}let Q=(await Q7()).get($)??[];if(Q.length===0)return null;let Y=L0.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 ZJ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await Y7($);if(J){let V=await lF(J,Z);return M4($,J),{chatId:J,created:!1,joined:V}}let Q=await K0.im.chat.create({params:{user_id_type:"open_id",uuid:Z7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw n0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return P0.set(Y,$),M4($,Y),{chatId:Y,created:!0,joined:!0}}async function JJ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await Y7($))throw Error(`temporary group name already exists: ${$}`);let Q=await K0.im.chat.create({params:{user_id_type:"open_id",uuid:Z7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw n0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return P0.set(Y,$),M4($,Y),{chatId:Y,created:!0,joined:!0}}async function QJ($){let Z=await Y7($);if(!Z)return t8($),{chatId:null,disbanded:!1};let J=await K0.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw n0("feishu chat.delete",J);if(P0.delete(Z),L0.get($)===Z)t8($);return{chatId:Z,disbanded:!0}}async function YJ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await NH(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!RH(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await K0.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw n0("feishu chat.delete",Q);return P0.delete(Z),{chatId:Z,disbanded:!0}}async function lF($,Z){let J;do{let Y=await K0.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 n0("feishu chatMembers.get",Y);for(let V of Y.data?.items??[])if(V.member_id===Z)return!1;J=Y.data?.page_token}while(J);let Q=await K0.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw n0("feishu chatMembers.create",Q);return!0}async function VJ($){try{let Z=await m$(),J=await m9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}}),Y=(await B$(J,`fetchChatName ${$}`)).data?.name;if(typeof Y==="string"&&Y)return P0.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 V7($,Z,J,Q,Y){let V=Z7();try{return await t1(`send${$} chat=${Z}`,async()=>{let X=await K0.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Q,uuid:V}});if(X?.code!==0)throw n0(`send${$}`,X);let z=X?.data?.message_id;if(typeof z!=="string"||!z.trim())throw Error(`send${$} message_id MISS`);return z})}catch(X){return Y?.(X),null}}async function NH($){let Z=await K0.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw n0("feishu chat.get",Z);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function RH($){return $===null||$==="normal"}async function b($,Z,J){return R$($,()=>V7("Text",$,"text",JSON.stringify({text:Z}),J))}async function n($,Z,J){return R$($,()=>V7("Card",$,"interactive",JSON.stringify(S1(Z)),J))}async function XJ($){let Z=await K0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw n0("feishu message.list",Z);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 E4($,Z){let J=await K0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(S1(Z))}});if(J?.code!==0)throw n0("feishu message.patch",J)}async function I($,Z){return R$($,()=>uF($,Z))}async function uF($,Z){try{let J=await m$(),Q=await m9("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})})});return(await B$(Q,`sendTextRaw chat=${$}`)).data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function X$($,Z){if(!$)return null;try{let J=await K0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}});if(J?.code&&J.code!==0)throw n0("feishu messageReaction.create",J);return J?.data?.reaction_id??null}catch(J){return B(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function g0($,Z){if(!$||!Z)return;try{let J=await K0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}});if(J?.code&&J.code!==0)throw n0("feishu messageReaction.delete",J)}catch(J){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function q2($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await m$(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let Y=await m9(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})}),X=(await B$(Y,`urgentApp ${$}`)).data?.invalid_user_id_list??[],z=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${z}${X.length?` invalid=${X.length}`:""}`)}catch(Y){B(`feishu: urgentApp ${$} failed: ${Y}`)}}async function l9($,Z,J,Q){try{let Y=await m$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await m9(V,{headers:{Authorization:`Bearer ${Y}`}});if(!X.ok)await B$(X,`download ${J}`);let z=Buffer.from(await X.arrayBuffer());fZ(Y5,{recursive:!0});let H=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=hZ(Y5,`${Date.now()}-${Z7()}-${H}`);return _H(G,z,{flag:"wx"}),B(`feishu: downloaded ${J} ${G} (${z.length}B)`),G}catch(Y){B(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function iF($){return dF.has(wF($).toLowerCase())}async function TH($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Q;return t1(`${J} ${$}`,async()=>{if(Q??=new Blob([Uint8Array.from(await kF($))]),Q.size>X7)throw Error(`${L2($)} 超过 30 MB`);let Y=await m$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",L2($));V.append(Z,Q,L2($));let z=(await FH(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:V},J)).data?.[`${Z}_key`];if(typeof z!=="string"||!z.trim())throw Error(`${J} ${Z}_key MISS`);return z})}async function zJ($,Z){try{let J=jH($);if(!J.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),Z?.(Error("路径不是普通文件")),null;if(J.size>X7)return B(`feishu: uploadImageKey oversize — ${$} (${(J.size/1024/1024).toFixed(1)} MB)`),Z?.(Error(`${L2($)} 超过 30 MB`)),null}catch(J){return B(`feishu: uploadImageKey stat failed — ${$}: ${J}`),Z?.(J),null}try{return await TH($,"image")}catch(J){return Z?.(J),null}}async function z7($,Z,J){return R$($,()=>V7("Image",$,"image",JSON.stringify({image_key:Z}),J))}async function EH($,Z,J){return R$($,()=>V7("File",$,"file",JSON.stringify({file_key:Z}),J))}async function u9($,Z){try{let Y=jH(Z);if(!Y.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await b($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>X7)return B(`feishu: uploadAndSend oversize — ${Z} (${Y.size}B)`),await b($,`❌ 出站文件: ${L2(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return B(`feishu: uploadAndSend stat failed — ${Z}: ${Y}`),await b($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=iF(Z)?"image":"file",Q=J==="image"?"出站图片":"出站文件";try{let Y=await TH(Z,J),V,X=(H)=>{V=H},z=await(J==="image"?z7($,Y,X):EH($,Y,X));if(!z)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await b($,`❌ ${Q}发送失败: ${L2(Z)}(上传已完成)
112
+ ${w(V)}`),!1;return B(`feishu: uploadAndSend ${Z} delivered msg=${z}`),!0}catch(Y){return B(`feishu: uploadAndSend ${Z} failed: ${Y}`),await b($,`❌ ${Q}上传失败: ${L2(Z)} — ${w(Y)}`),!1}}function HJ($){fZ($,{recursive:!0}),B(`feishu: provisioned ${$}`);let Z=hZ(zH(),".codex","config.toml");try{fZ(hZ(zH(),".codex"),{recursive:!0});let J="";try{J=P2(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
112
113
 
113
114
  `:""}${Q}
114
115
  trust_level = "trusted"
115
- `,zH(Z,J)}}catch(J){B(`feishu: codex trust write failed for ${$}: ${J}`)}try{qF("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function u9($=c){let Z=UF(F9(),["login","status",...y.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:y.env($,{...process.env,...m.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}
116
- ${Z.stderr}`)}function HJ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var GH,WH,gZ,Y$,C1=async($)=>{try{let Z=await e8.defaultHttpInstance.request({...$,$return_headers:!0}),J=A$({data:Z.data,headers:Z.headers});if(J.logId&&Z.data&&typeof Z.data==="object"&&!Array.isArray(Z.data))Z.data.log_id=J.logId;return $.$return_headers?Z:Z.data}catch(Z){if(Z instanceof Error){let J=A$(Z);Z.message=v(Z),Object.assign(Z,{apiMessage:J.message,logId:J.logId})}throw Z}},OF,K0,KH=15000,o8="",ZH=0,vZ=null,L0,P0,A0,Q0,YH=200,VH,I0,V7=31457280,bF;var $0=N(()=>{p0();o2();DZ();_0();f0();J1();_0();H0();h();j0();x0();U4();h0();r1();ez();GH=m.feishu.app_id,WH=m.feishu.app_secret,gZ=m.runtime.projects_root,Y$=new Map;OF={request:C1,get:($,Z)=>C1({...Z,url:$,method:"GET"}),delete:($,Z)=>C1({...Z,url:$,method:"DELETE"}),head:($,Z)=>C1({...Z,url:$,method:"HEAD"}),options:($,Z)=>C1({...Z,url:$,method:"OPTIONS"}),post:($,Z,J)=>C1({...J,url:$,data:Z,method:"POST"}),put:($,Z,J)=>C1({...J,url:$,data:Z,method:"PUT"}),patch:($,Z,J)=>C1({...J,url:$,data:Z,method:"PATCH"})},K0=new e8.Client({appId:GH,appSecret:WH,disableTokenCache:!1,httpInstance:OF});L0=new Map,P0=new Map;A0=new Map;Q0=new Map;VH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;I0=new Map;bF=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});async function MH($=(Z)=>new N$({accountId:Z})){if(M1(c))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Q;try{Z=$(c),await Z.initialize("lodestar-login-check"),Q=await h$(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Y){J=Error(`默认账号登录检查失败:${x4(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,`默认账号检查进程关闭失败:${x4(Y).message}`].filter(Boolean).join(";"),{cause:Y})}if(J)throw J}class OH{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Y)=>new N$({accountId:Y,login:!0}),Z=900000,J=(Y,V)=>{y.recordLogin(Y,V),f$(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=jX($),Q;try{Q=this.createClient($)}catch(H){throw J(),H}let Y,V,X=new Promise((H,G)=>{Y=H,V=G});X.catch(()=>{});let z={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};z.notification=(H,G)=>{if(z.finishing||!z.loginRequested)return;if(H==="account/updated"){if(G?.authMode==="chatgpt"){if(z.authUpdated=!0,z.loginSucceeded)this.finish(z)}return}if(H!=="account/login/completed")return;if(!z.loginId){z.early.push(G);return}if(G?.loginId!==z.loginId)return;if(G?.success!==!0){this.finish(z,Error(typeof G?.error==="string"?G.error:"Codex 登录未成功"));return}if(z.loginSucceeded)return;if(z.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${z.authUpdated}`),z.timer)clearTimeout(z.timer);if(z.authUpdated)this.finish(z);else z.timer=setTimeout(()=>{this.finish(z,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},z.closed=(H)=>{this.finish(z,H)},Q.on("notification",z.notification),Q.on("closed",z.closed),Q.on("protocolError",z.closed),this.attempts.set($,z);try{await Q.initialize("lodestar-login"),z.loginRequested=!0;let H=await Q.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(H?.type!=="chatgptDeviceCode"||typeof H.loginId!=="string"||!H.loginId||typeof H.userCode!=="string"||!H.userCode||typeof H.verificationUrl!=="string"||new URL(H.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(z.loginId=H.loginId,z.finishing)throw await X,Error("登录已结束");z.timer=setTimeout(()=>{this.cancelAttempt(z,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let G of z.early)z.notification("account/login/completed",G);return z.early.length=0,{accountId:$,loginId:H.loginId,verificationUrl:H.verificationUrl,userCode:H.userCode,done:X}}catch(H){return await this.finish(z,x4(H)),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};取消请求失败:${x4(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=x4(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,`登录进程关闭失败:${x4(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 x4($){return $ instanceof Error?$:Error(String($))}var q2;var GJ=N(()=>{J$();j0();h();q2=new OH});import{readFileSync as wF}from"node:fs";import{homedir as vF}from"node:os";import{join as TH}from"node:path";function fF(){return process.env.CLAUDE_CONFIG_DIR||TH(vF(),".claude")}function WJ(){try{let $=wF(TH(fF(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function D2($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function hF($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function IF($){let Z=hF($);return Z&&D2($)?Z:null}function NH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function RH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function gF($){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"),Q=J.find((W)=>W?.unit===3&&W?.number===5),Y=J.find((W)=>W?.unit===6&&W?.number===1),V=Z.find((W)=>W?.type==="TIME_LIMIT"),X=(W)=>W?{percent:NH(W.percentage),resetsAt:RH(W.nextResetTime)}:null,z=X(Q),H=X(Y),G=V?{percent:NH(V.percentage),resetsAt:RH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!z&&!H&&!G)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:z,weekly:H,monthly:G,fetchedAt:Date.now()}}async function z7($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:WJ(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let V=IF(Y);if(!V)return{state:"not_glm",baseUrl:Y||void 0};return yF.readStale(P$("glm",V,Q),()=>mF(V,Q))}async function mF($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Q=new AbortController,Y=setTimeout(()=>Q.abort(),AH);try{let V=await V0(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:y$(V.headers)};let X=await V.json(),z=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||z!==void 0&&String(z)!=="200"){let W=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[z===void 0?"":`code ${z}`,W===void 0?"":String(W)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(z)==="429"?"rate_limited":"network",reason:K,retryAfterMs:y$(V.headers)}}let H=X?.data??X,G=gF(H);if(G.state==="network")B(`glm-usage: quota/limit MISS: ${G.reason}`);return G}catch(V){let X=(V?.name==="AbortError"?`timeout ${AH}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 AH=1e4,yF;var H7=N(()=>{p0();h();Q1();yF=new Z$});function c$($){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 S4($){let Z=c$($),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)?pF:Z}function KJ($,Z){let J=c$($),Q=P$("packy-models",J,Z),Y=G7.get(Q);if(Y)return Y;let V=v$(`${J}/v1/models`,Z,"PackyAPI models").then((X)=>{let z=new Set;return X.map((H)=>{if(typeof H.id!=="string"||!H.id.trim()||z.has(H.id)||!Array.isArray(H.supported_endpoint_types)||!H.supported_endpoint_types.length||!H.supported_endpoint_types.every((G)=>typeof G==="string"&&G))throw Error("PackyAPI 模型目录缺少有效 id/协议声明,或含重复模型");return z.add(H.id),{id:H.id,display:typeof H.name==="string"&&H.name?H.name:H.id,protocols:[...H.supported_endpoint_types],...p$(H.reasoning)?{reasoning:H.reasoning}:{}}})}).finally(()=>{if(G7.get(Q)===V)G7.delete(Q)});return G7.set(Q,V),V}function p$($){return $!==null&&typeof $==="object"&&!Array.isArray($)}async function K7($,Z,J={}){let Q=await V0($,{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 z1(Q.status,"响应不是有效 JSON",y$(Q.headers))}let X=p$(V)?V.code:void 0,z=X!==void 0&&![!0,0,200,"0","200"].some((H)=>H===X);if(!Q.ok||!p$(V)||V.success===!1||z||V.error!=null){let H=p$(V)&&p$(V.error)?V.error.message:p$(V)?V.message:null;throw new z1(Q.status,typeof H==="string"?H:"上游接口返回错误",y$(Q.headers))}return V}async function BJ($,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=c$($),V=P$("packy-balance",Y,JSON.stringify([J,Z])),X=async()=>{try{let H=await K7(`${Y}/api/user/self`,Z,{"New-Api-User":J}),G=H.data;if(H.success!==!0||!p$(G)||G.id!==Number(J))throw Error("PackyAPI 账户响应缺少成功状态,或用户 ID 与余额凭据不匹配");if(typeof G.quota!=="number"||!Number.isSafeInteger(G.quota))throw Error("PackyAPI 账户余额 quota 缺失或无效");let W=(await K7(`${Y}/api/status`)).data;if(!p$(W)||typeof W.quota_per_unit!=="number"||!Number.isFinite(W.quota_per_unit)||W.quota_per_unit<=0||W.quota_display_type!=="USD")throw Error("PackyAPI 账户余额单位缺失或不是已支持的 USD 单位");let K=G.quota/W.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(H){let G=c0(H,[Z]);return B(`PackyAPI balance MISS: ${G}`),{state:H instanceof z1&&[401,403].includes(H.status)?"no_credentials":H instanceof z1&&H.status===429?"rate_limited":"network",kind:"balance",windows:[],reason:G,...H instanceof z1&&H.retryAfterMs!==void 0?{retryAfterMs:H.retryAfterMs}:{}}}};if(!Q)return W7.readStale(V,X);let z=await X();if(z.state==="ok")W7.prime(V,z);else W7.invalidate(V);return z}async function EH($,Z){if(!Z)return{state:"no_credentials",kind:"quota",windows:[]};let J=S4($);return W7.readStale(P$("packy",J,Z),async()=>{try{let Y=(await K7(`${J}/api/usage/token/`,Z)).data;if(!p$(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 z=(await K7(`${J}/api/status`)).data;if(!p$(z)||typeof z.quota_per_unit!=="number"||!Number.isFinite(z.quota_per_unit)||z.quota_per_unit<=0||z.quota_display_type!=="USD")throw Error("PackyAPI 配额单位缺失或不是已支持的 USD 额度单位");return{state:"ok",kind:"quota",windows:[],fetchedAt:Date.now(),quota:{remaining:V/z.quota_per_unit,limit:X/z.quota_per_unit,currency:"USD"}}}catch(Q){let Y=c0(Q,[Z]);return B(`PackyAPI quota MISS: ${Y}`),{state:Q instanceof z1&&[401,403].includes(Q.status)?"no_credentials":Q instanceof z1&&Q.status===429?"rate_limited":"network",kind:"quota",windows:[],reason:Y,...Q instanceof z1&&Q.retryAfterMs!==void 0?{retryAfterMs:Q.retryAfterMs}:{}}}})}var F2="https://cf.api.fan",pF="https://www.packyapi.ai",G7,z1,W7;var jJ=N(()=>{p0();s2();Q1();h();G7=new Map;z1=class z1 extends Error{status;retryAfterMs;constructor($,Z,J){super(`PackyAPI HTTP ${$}: ${Z}`);this.status=$;this.retryAfterMs=J}};W7=new Z$});function xH($){return _7.find((Z)=>Z.other===$)?.id??$}function SH($){let Z=_7.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function d9($){let Z=$.api_key?.trim(),J=$.auth_token?.trim();if(Z&&J&&Z!==J)throw Error("同一账号的 api_key 与 auth_token 不一致,请重新配置");return Z||J}function j7($,Z){if($.id==="packy")return c$(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 z9(`${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 B7($,Z){let J=j7($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function C4($){let{api_key:Z,auth_token:J,base_url:Q,...Y}=$;return Y}function _J($,Z,J={}){let Q=Z[$.id]??{},Y=Z[$.other]??{},V=d9(Q),X=d9(Y),z=Q.base_url?.trim(),H=Y.base_url?.trim();if(V&&X&&V!==X||z&&H&&B7($,z)!==B7($,H))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:j7($,z||H||$.base)};let G=J[$.id]??J[$.other]??{};if(d9(G)&&(z||H)&&G.base_url&&B7($,z||H)!==B7($,G.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:d9(G),base:j7($,z||H||G.base_url||$.base)}}function i9($,Z={}){let J={...$};for(let Q of _7){let{key:Y,base:V}=_J(Q,$,Z);J[Q.id]={...C4($[Q.id]??{}),base_url:V,...Q.id==="glm"?{auth_token:Y??""}:{api_key:Y??""}},J[Q.other]={...C4($[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 cF(J),J}function cF($){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 z=$[X]??{},H=z.billing_source?.trim(),G=H||(X==="packy-codex"&&!Y(z)?"packy":void 0);if(G){if(!Z.has(G)||!$[G])throw Error(`PackyAPI 余额账号引用不存在:${G}`);if(H&&Y(z))throw Error(`PackyAPI ${X} 不能同时配置 billing_source 和独立余额凭据`);let W=V(G);$[X]={...z,...H||Y(W)||W.billing_source?{billing_source:G,management_token:W.management_token,management_user_id:W.management_user_id,management_url:W.management_url||S4(W.base_url||F2)}:{}}}return Q.delete(X),J.add(X),$[X]??z};for(let X of Z)if($[X])V(X)}function PJ($,Z,J){let Q=Object.fromEntries(Object.entries(J).filter(([,H])=>H!==void 0)),Y={...$,[Z]:{...$[Z],...Q}},V=_7.find((H)=>H.id===Z||H.other===Z);if(!V)return{[Z]:Y[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,z=J.base_url!==void 0;if(X||z){let H=$[Z]??{},G=$[V.id]??{},W=$[V.other]??{},K=X?d9(J):_J(V,$).key,j=j7(V,J.base_url?.trim()||H.base_url||G.base_url||W.base_url||V.base);Y[V.id]={...C4(Y[V.id]??{}),base_url:j,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Y[V.other]=C4(Y[V.other]??{})}else{let{key:H,base:G}=_J(V,Y);Y[V.id]={...C4(Y[V.id]??{}),base_url:G,...V.id==="glm"?{auth_token:H??""}:{api_key:H??""}},Y[V.other]=C4(Y[V.other]??{})}return{[V.id]:Y[V.id],[V.other]:Y[V.other]}}var _7;var n9=N(()=>{H9();jJ();_7=[{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 uF($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function P7($,Z,J){try{let Q=await V0(uF($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(lF)});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 lF=15000;var LJ=N(()=>{p0();h()});function CH($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function dF($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function bH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function iF($){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 nF($){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 qJ($){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(CH($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(CH($.weekly,"weekly","周额度"));if($.monthly)Z.push(dF($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var DJ=N(()=>{X0();H7();L4();C9();LJ();h();H9();D0({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)&&D2(J),V=$.model?.trim()||void 0,X=nF($.slots),z={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(!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await Sz(J,Q),W=[...new Set([...bH($.models),...bH($.custom_models)])].filter((K)=>!H.some((j)=>j.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:P4,defaultEffort:"max",origin:"custom"}));if(z.models=[...H,...W],!V)z.defaultModel=iF(z.models.map((K)=>K.model));for(let K of z.models){let j=B4("glm",K.model);K.context1m=j!=null&&j>=1e6||void 0}z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){B(`glm refreshModels MISS: ${H?.message??H}`),z.models=[],z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let W={...u0(H)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_AUTH_TOKEN=Q,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(H){return v8("glm",H)},async verifyModel(H){return P7(J,{Authorization:`Bearer ${Q}`},H)},async readUsage(){return qJ(await z7(J,Q))}};return z},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:z9(Z.length===2?Z[0]:t2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await r2($.base_url??t2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!D2(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var kH=N(()=>{X0();L4();D0({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 m8(),!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}})});import{homedir as aF}from"node:os";function q7($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function L7($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!q7($))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 vH($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function yH($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=vH(E9(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&&vH(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 sF($){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=[L7(Z.five_hour,"fiveHour","5h 窗口"),L7(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(L7(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(!q7(Y)||typeof Y.display_name!=="string"||!Y.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Y.display_name.trim();J.push(L7(Y,`modelWeekly:${V}`,`${V} 周额度`)),Q=!0}}if(!Q)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function fH($){return oF.readStale("claude-subscription",()=>tF($))}async function tF($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (_4(),jZ)),J=new Z({workDir:aF(),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,z)=>{Q=setTimeout(()=>z(Error(`Claude 订阅额度查询超时(${wH/1000}s)`)),wH)})]);return sF(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":Y2(Z)?"rate_limited":"network",windows:[],reason:J}}}var wH=30000,oF;var FJ=N(()=>{h();VZ();Q1();oF=new Z$});function rF(){let $=Object.fromEntries(b8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function eF($){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 hH=N(()=>{_0();h();X0();L4();FJ();V1();D0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=rF(),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:eF,spawnEnv(X){return{...u0(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 m8({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id});if(!X.length)throw Error("Claude Code 订阅模型目录为空");let z=[...r($.custom_models),...r($.models)];if(J&&!X.some((H)=>H.model===J)&&!z.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let H=X.find((G)=>G.model===(J??X[0].model));if(!R0($.effort)||H&&!H.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(H)H.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let z=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${z}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:z}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Y??=fH({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Y=void 0}),Y}};return V}})});function gH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function $U($){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 ZU($){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 JU($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function mH($,Z){return(await UJ(new URL($).origin,Z)).map((Q)=>({model:Q,display:Q,efforts:P4,defaultEffort:"high"}))}async function UJ($,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 v$(`${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 MJ($,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 YU.readStale(P$("deepseek",J,Z),()=>VU(J,Z))}async function VU($,Z){try{let J=await V0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(QU)});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:y$(J.headers)};let Q=await J.json(),V=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",z=V?.total_balance;if(!X||typeof z!=="string"&&typeof z!=="number"||String(z).trim()===""||!Number.isFinite(Number(z)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(z),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var IH="https://api.deepseek.com/anthropic",QU=1e4,YU;var OJ=N(()=>{p0();X0();L4();C9();LJ();h();s2();Q1();YU=new Z$;D0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||IH,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,V=$.model?.trim()||void 0,X=ZU($.slots),z={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(!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await mH(J,Q),W=[...new Set([...gH($.models),...gH($.custom_models)])].filter((K)=>!H.some((j)=>j.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:P4,defaultEffort:"high",origin:"custom"}));if(z.models=[...H,...W],!V)z.defaultModel=$U(z.models.map((K)=>K.model));for(let K of z.models){let j=B4("deepseek",K.model);K.context1m=j!=null&&j>=1e6||void 0}z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){B(`deepseek refreshModels MISS: ${H?.message??H}`),z.models=[],z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let W={...u0(H)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_API_KEY=Q,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(H){return v8("deepseek",H)},async verifyModel(H){return P7(J,{"x-api-key":Q},H)},async readUsage(){if(!Q)return{kind:"balance",state:"no_credentials",windows:[]};return MJ(J,Q)}};return z},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 mH($.base_url??IH,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!JU(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function U2($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var AJ;var pH=N(()=>{AJ=[{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 M2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function RJ($){return $ instanceof Error?$.message:String($)}function lH($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function b4($){return $.replace(/\[1m\]$/,"")}function k4($){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 HU($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Q=await V0(`${k4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(XU)});if(!Q.ok){let Y=await Q.text(),V="";if(Y.trim().startsWith("{"))try{let X=JSON.parse(Y);if(M2(X)&&M2(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new D7(Q.status,V.replaceAll(Z,"[redacted]"),y$(Q.headers))}return Q.json()}async function uH($,Z){let J=await v$(`${k4($)}/v1/models/user`,Z,"OpenRouter models"),Q=[],Y=new Set;for(let V of J){if(!M2(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!M2(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(U2(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Y.has(V.id))continue;let X=M2(V.reasoning)?V.reasoning:void 0,z=X?.supported_efforts,H=z===null||z===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(z)?[...new Set(z.filter((j)=>j!=="default"&&R0(j)))]:["default"],G=AJ.find((j)=>j.model===V.id),W=G?H.includes(G.effort)?G.effort:null:H[0]==="default"?"default":R0(X?.default_effort)&&H.includes(X.default_effort)?X.default_effort:null,K=B4("openrouter",V.id);Q.push({model:V.id,display:V.name,efforts:H,defaultEffort:W,context1m:K!==void 0&&K>=1e6||void 0}),Y.add(V.id)}if(!Q.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Q}function dH($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function GU($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return zU.readStale(P$("openrouter",k4($),Z),()=>WU($,Z))}async function WU($,Z){try{let J=await HU($,Z,"credits");if(!M2(J)||!M2(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Q,total_usage:Y}=J.data;if(!dH(Q)||!dH(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=RJ(J);return B(`openrouter readUsage MISS: ${Q}`),{kind:"balance",state:J instanceof D7&&J.status===429?"rate_limited":"network",windows:[],reason:Q,...J instanceof D7?{retryAfterMs:J.retryAfterMs}:{}}}}var cH="https://openrouter.ai/api",XU=1e4,zU,NJ,D7;var iH=N(()=>{p0();_0();X0();C9();h();pH();s2();Q1();zU=new Z$,NJ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};D7=class D7 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};D0({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()||cH,V=$.model?.trim()||"",X=$.models===void 0?AJ.map((H)=>H.model):lH($.models),z={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Q,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(H){if(U2(H))throw Error(`OpenRouter 已排除此厂商或自动路由: ${H}`);if(!H.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(H){let G=z.modelSelection.availableModels.find((W)=>b4(W.model)===b4(H));if(!G||G.unavailableReason||!G.efforts.length)return"model-unavailable";return G.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(z.models=[],z.modelSelection.availableModels=[],!z.enabled){z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await uH(Y,Q),G=H.find((K)=>K.model===b4(V));if(V&&!G)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!R0($.effort)||!G.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);G.defaultEffort=$.effort}let W=X.map((K)=>{let j=H.find((_)=>_.model===b4(K));if(!j)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:U2(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{...j,model:K}});z.models=W,z.modelSelection.availableModels=H,z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){let G=RJ(H);B(`openrouter refreshModels MISS: ${G}`),z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G}}},spawnEnv(H,G){if(!Q)throw Error("OpenRouter API key missing");let W=G||V;if(!W)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(U2(W))throw Error(`OpenRouter 已排除此厂商或自动路由: ${W}`);let K=u0(H);K.ANTHROPIC_BASE_URL=k4(Y),K.ANTHROPIC_AUTH_TOKEN=Q,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 j of Object.values(NJ))K[j]=W;for(let j of lH($.slots)){let _=j.indexOf("="),D=j.slice(0,_).trim(),L=j.slice(_+1).trim();if(_<1||!Object.hasOwn(NJ,D)||!L)throw Error(`OpenRouter slots 无效: ${j}`);if(U2(L)||!z.modelSelection.availableModels.some((P)=>!P.unavailableReason&&b4(P.model)===b4(L)))throw Error(`OpenRouter slot 模型不在账号目录中: ${L}`);if(z.modelEnvironmentRevision(L)!==z.modelEnvironmentRevision(W))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${L}`);K[NJ[D]]=L}return K},resolveSpawnModel(H){if(U2(H))throw Error(`OpenRouter 已排除此厂商或自动路由: ${H}`);return H||void 0},readUsage(){return GU(Y,Q)}};return z},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:k4(Z[0])}:{}}}}catch(J){return{error:RJ(J)}}},async validate($){await uH($.base_url??cH,$.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=k4(Z);if(new URL(Q).hostname!=="openrouter.ai")return null;return{base_url:Q,api_key:J}}catch{return null}}}})});function BU($){return $.trim().replace(/\[1m\]$/,"").toLowerCase().split("/").at(-1)??""}function aH($,Z="packy"){return KU[Z].includes(BU($))}var nH,KU;var oH=N(()=>{nH=["minimax-m3","claude-opus-5","claude-fable-5-1","qwen3.8-max-0902"],KU={packy:nH,"packy-secondary":nH,"packy-codex":["kimi-k3","grok-4.6"]}});function EJ($){return $.replace(/\[1m\]$/,"")==="gemini-3.8-flash"}function jU($,Z,J){let Q=Z==="claude"?T9:Q2,Y=$.reasoning?.supported_efforts;if(Y!==void 0&&(!Array.isArray(Y)||!Y.length||!Y.every((H)=>typeof H==="string")))throw Error(`PackyAPI ${$.id} 的推理档位声明无效`);let V=Y===void 0?[...Q]:Q.filter((H)=>Y.includes(H));if(!V.length)throw Error(`PackyAPI ${$.id} 未声明当前 Agent 可用的推理档位`);let X=J.effort?.trim(),z=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 z==="string"&&V.includes(z)?z:null}}var TJ="LODESTAR_PACKY_API_KEY",sH,tH;var rH=N(()=>{_0();J1();jJ();oH();V1();h();Q1();X0();sH={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"};tH=[{id:"packy",agent:"claude",display:"PackyAPI"},{id:"packy-secondary",agent:"claude",display:"PackyAPI · 令牌2"},{id:"packy-codex",agent:"codex",display:"PackyAPI"}];for(let $ of tH){let{id:Z,agent:J,display:Q}=$,Y=J==="claude"?"anthropic":"openai-response",V=(X)=>X.protocols.includes(Y)||J==="claude"&&EJ(X.id);D0({kind:Z,configSectionId:Z,build(X){let z=X.api_key?.trim()||X.auth_token?.trim()||"",H=c$(X.base_url?.trim()||F2),G=X.management_url?.trim()?c$(X.management_url):S4(H),W=X.management_token?.trim()||"",K=X.management_user_id?.trim()||"",j=!!(W||K||X.management_url?.trim()||X.billing_source?.trim()),_=X.model?.trim(),D=X.models===void 0?void 0:r(X.models),L=new Set([...r(X.custom_models),...D??[]]),P=(M)=>aH(M,Z),F=[],U=(M)=>{let O=F.find((R)=>R.id===M);if(O&&!V(O)&&!L.has(M))throw Error(`PackyAPI ${M} 未声明 ${Y};确认兼容后可显式补录`)},A={id:Z,kind:Z,agent:J,display:X.display?.trim()||Q,enabled:!!z&&X.enabled!==!1,models:[],defaultModel:_??"",modelSelection:{mode:"allowlist",modelIds:D??[],availableModels:[]},...j?{usageAccount:{id:P$("packy-account",G,K),label:"PackyAPI"}}:{},modelCatalogState:{status:z&&X.enabled!==!1?"idle":"disabled",updatedAt:Date.now()},...J==="claude"?{modelEnvironmentRevision(M){return EJ(M)?JSON.stringify(sH):"native-retries"}}:{},...J==="codex"?{codexApiProvider:{id:"packy",name:"PackyAPI",baseUrl:`${H}/v1`,envKey:TJ}}:{},async refreshModels(){if(A.models=[],F=[],!A.enabled){A.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}A.modelCatalogState={status:"loading",updatedAt:null};try{F=await KJ(H,z);let M=F.filter((T)=>V(T)||L.has(T.id));if(!M.length&&!L.size)throw Error(`PackyAPI 此令牌没有声明支持 ${Y} 的模型,请检查分组和模型限制`);let O=M.map((T)=>({...jU(T,J,X),...!T.protocols.includes(Y)&&L.has(T.id)?{origin:"custom"}:{}}));for(let T of L){if(O.some((f)=>f.model.toLowerCase()===T.toLowerCase()))continue;O.push({model:T,display:T,origin:"custom",...K2(A,X)})}if(_&&!O.some((T)=>T.model===_)){if(F.find((f)=>f.id===_))throw Error(`PackyAPI ${_} 未声明 ${Y},确认兼容后请显式补录`);if(!L.has(_))throw Error(`PackyAPI 默认模型不在目录中且未补录: ${_}`)}let R=D??O.filter((T)=>T.origin==="custom"||P(T.model)).map((T)=>T.model);if(D===void 0&&_&&!R.some((T)=>T.toLowerCase()===_.toLowerCase()))R.unshift(_);let w=R.map((T)=>O.find((f)=>f.model===T)??{model:T,display:T,efforts:[],defaultEffort:null,unavailableReason:"账号目录未返回该模型"});A.modelSelection.availableModels=O,A.models=w,A.modelSelection.modelIds=w.map((T)=>T.model),A.defaultModel=_??w.find((T)=>!T.unavailableReason)?.model??[...L][0]??"",A.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(M){A.models=[],F=[];let O=c0(M,[z]);B(`${Z} refreshModels MISS: ${O}`),A.modelCatalogState={status:"failed",updatedAt:Date.now(),error:O}}},resolveSpawnModel(M){return U(M),M},spawnEnv(M,O){if(!z)throw Error("PackyAPI API key missing");let R=O||A.defaultModel;if(!R)throw Error("PackyAPI 尚未选择模型");U(R);let w=u0(M);if(delete w[TJ],J==="codex"){for(let f 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[f];return w[TJ]=z,w}if(w.ANTHROPIC_BASE_URL=H,w.ANTHROPIC_AUTH_TOKEN=z,w.ANTHROPIC_API_KEY="",w.CLAUDE_CODE_NO_MODEL_FALLBACK="1",EJ(R))Object.assign(w,sH);w.ANTHROPIC_MODEL=R,w.ANTHROPIC_SMALL_FAST_MODEL=R,w.CLAUDE_CODE_SUBAGENT_MODEL=R;for(let f of["OPUS","SONNET","HAIKU","FABLE"])w[`ANTHROPIC_DEFAULT_${f}_MODEL`]=R;let T={opus:"OPUS",sonnet:"SONNET",haiku:"HAIKU",fable:"FABLE"};for(let f of r(X.slots)){let[u,C,g]=f.split("=");if(!u||!Object.hasOwn(T,u)||!C||g!==void 0)throw Error(`PackyAPI slots 无效: ${f}`);if(!R1(A).some((Y0)=>Y0.model===C))throw Error(`PackyAPI slot 模型不在当前来源: ${C}`);U(C),w[`ANTHROPIC_DEFAULT_${T[u]}_MODEL`]=C}return w},readUsage(){return j?BJ(G,W,K):EH(H,z)}};return A},setup:{commandSuffix:Z,hint:()=>`发送 \`${Z}-setup [base_url] <api_key>\` 配置${Q}。${Z==="packy-codex"?"与 PackyAPI 主账号共用凭据。":""}`,parseArgs(X){let z=X.trim().split(/\s+/).filter(Boolean);if(z.length<1||z.length>2||/^https?:\/\//i.test(z.at(-1)))return{error:`用法: ${Z}-setup [base_url] <api_key>`};try{return{config:{agent:J,api_key:z.at(-1),base_url:c$(z.length===2?z[0]:F2)}}}catch(H){return{error:c0(H,[z.at(-1)])}}},async validate(X){if(!(await KJ(X.base_url??F2,X.api_key??X.auth_token??"")).some(V)&&!r(X.custom_models).length&&!r(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 z=X.trim().split(/\s+/).filter(Boolean);if(z.length===2&&z[0]==="share"){if(!tH.some((W)=>W.id===z[1])||z[1]===Z)return{error:"请指定另一个已配置的 PackyAPI 来源:packy、packy-secondary 或 packy-codex"};return{config:{billing_source:z[1],management_token:"",management_user_id:"",management_url:""}}}if(z.length<2||z.length>3)return{error:`用法:${Z}-balance-setup [management_url] <user_id> <system_token>,或 ${Z}-balance-setup share <source_id>`};let H=z.at(-2),G=z.at(-1);if(!/^[1-9]\d*$/.test(H)||!Number.isSafeInteger(Number(H)))return{error:"用户 ID 必须是正整数"};try{return{config:{billing_source:"",management_token:G,management_user_id:H,management_url:z.length===3?c$(z[0]):""}}}catch(W){return{error:c0(W,[G])}}},async validate(X){let z=X.management_url||S4(X.base_url||F2),H=await BJ(z,X.management_token||"",X.management_user_id||"",!0);if(H.state!=="ok")throw Error(H.reason||"PackyAPI 真实账户余额查询失败")}}}})}});var eH=1;import{EventEmitter as _U}from"node:events";import{createRequire as PU}from"node:module";import{createHash as LU,randomUUID as qU}from"node:crypto";import{createInterface as DU}from"node:readline";import{dirname as FU,join as H1,isAbsolute as UU}from"node:path";import{fileURLToPath as xJ}from"node:url";import{tmpdir as MU}from"node:os";import{existsSync as $G,mkdirSync as ZG,mkdtempSync as OU,readFileSync as a9,renameSync as AU,writeFileSync as JG,rmSync as SJ}from"node:fs";import NU from"cross-spawn";function RU($){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 TU($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=a9(H1($,".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,z=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(!z)throw Error(`DSH does not support MCP transport ${X.type} for ${Y}`);return{id:`lodestar-mcp-${Y}`,name:"@deepseek-ai/dsh-mcp-client",config:{...z,failOnStartupError:!0}}})}async function w4($,Z,J={}){let Q=new F7($);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 F7;var o9=N(()=>{H0();Z4();h();F7=class F7 extends _U{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!UU($.cwd))throw Error("DSH requires an absolute workspace");let Z=V8("dsh"),Q=PU(H1(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Y=JSON.parse(a9(Q,"utf8"));B(`dsh runtime: ${Y.version} (${Z})`);let V=RU($.env),X=$.home??i2;ZG(X,{recursive:!0,mode:448});let z=TU($.cwd,$.profile);this.launchDir=OU(H1(MU(),"lodestar-dsh-"));let H=import.meta.url.endsWith(".ts"),G=H?"dsh-bridge.ts":"dsh-bridge.js",W=a9(xJ(new URL(`./${G}`,import.meta.url))),K=H?a9(xJ(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),j=JSON.parse(a9(xJ(new URL("../package.json",import.meta.url)),"utf8")),_=Buffer.from(JSON.stringify({name:j.name,version:j.version,type:"module",private:!0})),D=LU("sha256").update(W).update(K).update(_).digest("hex").slice(0,20),L=H1(Z,".lodestar-bridges",D);ZG(L,{recursive:!0});let P=H1(L,G),F=(T,f)=>{if($G(T))return;let u=`${T}.${qU()}.tmp`;try{JG(u,f),AU(u,T)}finally{if($G(u))SJ(u)}};if(F(H1(L,"package.json"),_),H)F(H1(L,"dsh-protocol.ts"),K);F(P,W);let U=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((T)=>({id:T,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"},...z]},...V],A=H1(this.launchDir,"bridge.patch.yml");JG(A,JSON.stringify(U),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",O=[H1(FU(Q),Y.bin.dsh),"--profile","sdk","--patch",A,...($.patches??[]).flatMap((T)=>["--patch",T])],R={...$.env};if(R.LODESTAR_AGENT_CAPABILITY&&R.LODESTAR_AGENT_URL)R.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:R.LODESTAR_AGENT_URL,capability:R.LODESTAR_AGENT_CAPABILITY});for(let T of Object.keys(R))if(T.startsWith("LODESTAR_AGENT_"))delete R[T];try{this.child=NU(M,O,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...R,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(T){throw SJ(this.launchDir,{recursive:!0,force:!0}),T}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(T)=>{this.stderr=(this.stderr+T).slice(-16384),B(`dsh stderr: ${T.trimEnd()}`)}),this.child.stdin.on("error",(T)=>this.transportFailure(T));let w=DU({input:this.child.stdout,crlfDelay:1/0});w.on("line",(T)=>this.receive(T)),this.exitTask=new Promise((T)=>{this.child.once("error",(f)=>this.transportFailure(f)),this.child.once("close",(f,u)=>{this.exited=!0,w.close();let C=Error(`DSH exited code=${f} signal=${u}
117
- ${this.stderr}`);this.rejectPending(C),SJ(this.launchDir,{recursive:!0,force:!0}),T(),this.emit("exit",{code:f,signal:u,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==eH||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
116
+ `,_H(Z,J)}}catch(J){B(`feishu: codex trust write failed for ${$}: ${J}`)}try{bF("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function d9($=l){let Z=vF(U9(),["login","status",...v.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:v.env($,{...process.env,...m.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}
117
+ ${Z.stderr}`)}function GJ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var PH,qH,mZ,Y$,C1=async($)=>{try{let Z=await $7.defaultHttpInstance.request({...$,$return_headers:!0}),J=A$({data:Z.data,headers:Z.headers});if(J.logId&&Z.data&&typeof Z.data==="object"&&!Array.isArray(Z.data))Z.data.log_id=J.logId;return $.$return_headers?Z:Z.data}catch(Z){if(Z instanceof Error){let J=A$(Z);Z.message=w(Z),Object.assign(Z,{apiMessage:J.message,logId:J.logId})}throw Z}},fF,K0,DH=15000,s8="",HH=0,yZ=null,P0,L0,A0,Y0,KH=200,BH,I0,X7=31457280,dF;var $0=R(()=>{p0();o2();FZ();_0();f0();J1();_0();H0();h();j0();x0();U4();h0();e1();XH();PH=m.feishu.app_id,qH=m.feishu.app_secret,mZ=m.runtime.projects_root,Y$=new Map;fF={request:C1,get:($,Z)=>C1({...Z,url:$,method:"GET"}),delete:($,Z)=>C1({...Z,url:$,method:"DELETE"}),head:($,Z)=>C1({...Z,url:$,method:"HEAD"}),options:($,Z)=>C1({...Z,url:$,method:"OPTIONS"}),post:($,Z,J)=>C1({...J,url:$,data:Z,method:"POST"}),put:($,Z,J)=>C1({...J,url:$,data:Z,method:"PUT"}),patch:($,Z,J)=>C1({...J,url:$,data:Z,method:"PATCH"})},K0=new $7.Client({appId:PH,appSecret:qH,disableTokenCache:!1,httpInstance:fF});P0=new Map,L0=new Map;A0=new Map;Y0=new Map;BH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;I0=new Map;dF=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});async function xH($=(Z)=>new N$({accountId:Z})){if(M1(l))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Q;try{Z=$(l),await Z.initialize("lodestar-login-check"),Q=await h$(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Y){J=Error(`默认账号登录检查失败:${x4(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,`默认账号检查进程关闭失败:${x4(Y).message}`].filter(Boolean).join(";"),{cause:Y})}if(J)throw J}class SH{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Y)=>new N$({accountId:Y,login:!0}),Z=900000,J=(Y,V)=>{v.recordLogin(Y,V),f$(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=LX($),Q;try{Q=this.createClient($)}catch(H){throw J(),H}let Y,V,X=new Promise((H,G)=>{Y=H,V=G});X.catch(()=>{});let z={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};z.notification=(H,G)=>{if(z.finishing||!z.loginRequested)return;if(H==="account/updated"){if(G?.authMode==="chatgpt"){if(z.authUpdated=!0,z.loginSucceeded)this.finish(z)}return}if(H!=="account/login/completed")return;if(!z.loginId){z.early.push(G);return}if(G?.loginId!==z.loginId)return;if(G?.success!==!0){this.finish(z,Error(typeof G?.error==="string"?G.error:"Codex 登录未成功"));return}if(z.loginSucceeded)return;if(z.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${z.authUpdated}`),z.timer)clearTimeout(z.timer);if(z.authUpdated)this.finish(z);else z.timer=setTimeout(()=>{this.finish(z,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},z.closed=(H)=>{this.finish(z,H)},Q.on("notification",z.notification),Q.on("closed",z.closed),Q.on("protocolError",z.closed),this.attempts.set($,z);try{await Q.initialize("lodestar-login"),z.loginRequested=!0;let H=await Q.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(H?.type!=="chatgptDeviceCode"||typeof H.loginId!=="string"||!H.loginId||typeof H.userCode!=="string"||!H.userCode||typeof H.verificationUrl!=="string"||new URL(H.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(z.loginId=H.loginId,z.finishing)throw await X,Error("登录已结束");z.timer=setTimeout(()=>{this.cancelAttempt(z,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let G of z.early)z.notification("account/login/completed",G);return z.early.length=0,{accountId:$,loginId:H.loginId,verificationUrl:H.verificationUrl,userCode:H.userCode,done:X}}catch(H){return await this.finish(z,x4(H)),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};取消请求失败:${x4(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=x4(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,`登录进程关闭失败:${x4(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 x4($){return $ instanceof Error?$:Error(String($))}var D2;var WJ=R(()=>{J$();j0();h();D2=new SH});import{readFileSync as nF}from"node:fs";import{homedir as aF}from"node:os";import{join as wH}from"node:path";function sF(){return process.env.CLAUDE_CONFIG_DIR||wH(aF(),".claude")}function KJ(){try{let $=nF(wH(sF(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function F2($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function tF($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function rF($){let Z=tF($);return Z&&F2($)?Z:null}function bH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function kH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function eF($){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"),Q=J.find((W)=>W?.unit===3&&W?.number===5),Y=J.find((W)=>W?.unit===6&&W?.number===1),V=Z.find((W)=>W?.type==="TIME_LIMIT"),X=(W)=>W?{percent:bH(W.percentage),resetsAt:kH(W.nextResetTime)}:null,z=X(Q),H=X(Y),G=V?{percent:bH(V.percentage),resetsAt:kH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!z&&!H&&!G)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:z,weekly:H,monthly:G,fetchedAt:Date.now()}}async function H7($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:KJ(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let V=rF(Y);if(!V)return{state:"not_glm",baseUrl:Y||void 0};return oF.readStale(L$("glm",V,Q),()=>$U(V,Q))}async function $U($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Q=new AbortController,Y=setTimeout(()=>Q.abort(),CH);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:y$(V.headers)};let X=await V.json(),z=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||z!==void 0&&String(z)!=="200"){let W=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[z===void 0?"":`code ${z}`,W===void 0?"":String(W)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(z)==="429"?"rate_limited":"network",reason:K,retryAfterMs:y$(V.headers)}}let H=X?.data??X,G=eF(H);if(G.state==="network")B(`glm-usage: quota/limit MISS: ${G.reason}`);return G}catch(V){let X=(V?.name==="AbortError"?`timeout ${CH}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 CH=1e4,oF;var G7=R(()=>{p0();h();Q1();oF=new Z$});function c$($){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 S4($){let Z=c$($),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)?ZU:Z}function BJ($,Z){let J=c$($),Q=L$("packy-models",J,Z),Y=W7.get(Q);if(Y)return Y;let V=v$(`${J}/v1/models`,Z,"PackyAPI models").then((X)=>{let z=new Set;return X.map((H)=>{if(typeof H.id!=="string"||!H.id.trim()||z.has(H.id)||!Array.isArray(H.supported_endpoint_types)||!H.supported_endpoint_types.length||!H.supported_endpoint_types.every((G)=>typeof G==="string"&&G))throw Error("PackyAPI 模型目录缺少有效 id/协议声明,或含重复模型");return z.add(H.id),{id:H.id,display:typeof H.name==="string"&&H.name?H.name:H.id,protocols:[...H.supported_endpoint_types],...p$(H.reasoning)?{reasoning:H.reasoning}:{}}})}).finally(()=>{if(W7.get(Q)===V)W7.delete(Q)});return W7.set(Q,V),V}function p$($){return $!==null&&typeof $==="object"&&!Array.isArray($)}async function B7($,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 z1(Q.status,"响应不是有效 JSON",y$(Q.headers))}let X=p$(V)?V.code:void 0,z=X!==void 0&&![!0,0,200,"0","200"].some((H)=>H===X);if(!Q.ok||!p$(V)||V.success===!1||z||V.error!=null){let H=p$(V)&&p$(V.error)?V.error.message:p$(V)?V.message:null;throw new z1(Q.status,typeof H==="string"?H:"上游接口返回错误",y$(Q.headers))}return V}async function jJ($,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=c$($),V=L$("packy-balance",Y,JSON.stringify([J,Z])),X=async()=>{try{let H=await B7(`${Y}/api/user/self`,Z,{"New-Api-User":J}),G=H.data;if(H.success!==!0||!p$(G)||G.id!==Number(J))throw Error("PackyAPI 账户响应缺少成功状态,或用户 ID 与余额凭据不匹配");if(typeof G.quota!=="number"||!Number.isSafeInteger(G.quota))throw Error("PackyAPI 账户余额 quota 缺失或无效");let W=(await B7(`${Y}/api/status`)).data;if(!p$(W)||typeof W.quota_per_unit!=="number"||!Number.isFinite(W.quota_per_unit)||W.quota_per_unit<=0||W.quota_display_type!=="USD")throw Error("PackyAPI 账户余额单位缺失或不是已支持的 USD 单位");let K=G.quota/W.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(H){let G=c0(H,[Z]);return B(`PackyAPI balance MISS: ${G}`),{state:H instanceof z1&&[401,403].includes(H.status)?"no_credentials":H instanceof z1&&H.status===429?"rate_limited":"network",kind:"balance",windows:[],reason:G,...H instanceof z1&&H.retryAfterMs!==void 0?{retryAfterMs:H.retryAfterMs}:{}}}};if(!Q)return K7.readStale(V,X);let z=await X();if(z.state==="ok")K7.prime(V,z);else K7.invalidate(V);return z}async function vH($,Z){if(!Z)return{state:"no_credentials",kind:"quota",windows:[]};let J=S4($);return K7.readStale(L$("packy",J,Z),async()=>{try{let Y=(await B7(`${J}/api/usage/token/`,Z)).data;if(!p$(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 z=(await B7(`${J}/api/status`)).data;if(!p$(z)||typeof z.quota_per_unit!=="number"||!Number.isFinite(z.quota_per_unit)||z.quota_per_unit<=0||z.quota_display_type!=="USD")throw Error("PackyAPI 配额单位缺失或不是已支持的 USD 额度单位");return{state:"ok",kind:"quota",windows:[],fetchedAt:Date.now(),quota:{remaining:V/z.quota_per_unit,limit:X/z.quota_per_unit,currency:"USD"}}}catch(Q){let Y=c0(Q,[Z]);return B(`PackyAPI quota MISS: ${Y}`),{state:Q instanceof z1&&[401,403].includes(Q.status)?"no_credentials":Q instanceof z1&&Q.status===429?"rate_limited":"network",kind:"quota",windows:[],reason:Y,...Q instanceof z1&&Q.retryAfterMs!==void 0?{retryAfterMs:Q.retryAfterMs}:{}}}})}var U2="https://cf.api.fan",ZU="https://www.packyapi.ai",W7,z1,K7;var _J=R(()=>{p0();s2();Q1();h();W7=new Map;z1=class z1 extends Error{status;retryAfterMs;constructor($,Z,J){super(`PackyAPI HTTP ${$}: ${Z}`);this.status=$;this.retryAfterMs=J}};K7=new Z$});function yH($){return L7.find((Z)=>Z.other===$)?.id??$}function fH($){let Z=L7.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function i9($){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){if($.id==="packy")return c$(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 H9(`${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 j7($,Z){let J=_7($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function C4($){let{api_key:Z,auth_token:J,base_url:Q,...Y}=$;return Y}function LJ($,Z,J={}){let Q=Z[$.id]??{},Y=Z[$.other]??{},V=i9(Q),X=i9(Y),z=Q.base_url?.trim(),H=Y.base_url?.trim();if(V&&X&&V!==X||z&&H&&j7($,z)!==j7($,H))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:_7($,z||H||$.base)};let G=J[$.id]??J[$.other]??{};if(i9(G)&&(z||H)&&G.base_url&&j7($,z||H)!==j7($,G.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:i9(G),base:_7($,z||H||G.base_url||$.base)}}function n9($,Z={}){let J={...$};for(let Q of L7){let{key:Y,base:V}=LJ(Q,$,Z);J[Q.id]={...C4($[Q.id]??{}),base_url:V,...Q.id==="glm"?{auth_token:Y??""}:{api_key:Y??""}},J[Q.other]={...C4($[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 JU(J),J}function JU($){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 z=$[X]??{},H=z.billing_source?.trim(),G=H||(X==="packy-codex"&&!Y(z)?"packy":void 0);if(G){if(!Z.has(G)||!$[G])throw Error(`PackyAPI 余额账号引用不存在:${G}`);if(H&&Y(z))throw Error(`PackyAPI ${X} 不能同时配置 billing_source 和独立余额凭据`);let W=V(G);$[X]={...z,...H||Y(W)||W.billing_source?{billing_source:G,management_token:W.management_token,management_user_id:W.management_user_id,management_url:W.management_url||S4(W.base_url||U2)}:{}}}return Q.delete(X),J.add(X),$[X]??z};for(let X of Z)if($[X])V(X)}function PJ($,Z,J){let Q=Object.fromEntries(Object.entries(J).filter(([,H])=>H!==void 0)),Y={...$,[Z]:{...$[Z],...Q}},V=L7.find((H)=>H.id===Z||H.other===Z);if(!V)return{[Z]:Y[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,z=J.base_url!==void 0;if(X||z){let H=$[Z]??{},G=$[V.id]??{},W=$[V.other]??{},K=X?i9(J):LJ(V,$).key,j=_7(V,J.base_url?.trim()||H.base_url||G.base_url||W.base_url||V.base);Y[V.id]={...C4(Y[V.id]??{}),base_url:j,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Y[V.other]=C4(Y[V.other]??{})}else{let{key:H,base:G}=LJ(V,Y);Y[V.id]={...C4(Y[V.id]??{}),base_url:G,...V.id==="glm"?{auth_token:H??""}:{api_key:H??""}},Y[V.other]=C4(Y[V.other]??{})}return{[V.id]:Y[V.id],[V.other]:Y[V.other]}}var L7;var a9=R(()=>{G9();_J();L7=[{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 YU($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function P7($,Z,J){try{let Q=await X0(YU($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(QU)});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 QU=15000;var qJ=R(()=>{p0();h()});function hH($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function VU($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function IH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function XU($){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 zU($){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 DJ($){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(hH($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(hH($.weekly,"weekly","周额度"));if($.monthly)Z.push(VU($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var FJ=R(()=>{z0();G7();P4();b9();qJ();h();G9();D0({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)&&F2(J),V=$.model?.trim()||void 0,X=zU($.slots),z={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(!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await fz(J,Q),W=[...new Set([...IH($.models),...IH($.custom_models)])].filter((K)=>!H.some((j)=>j.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:L4,defaultEffort:"max",origin:"custom"}));if(z.models=[...H,...W],!V)z.defaultModel=XU(z.models.map((K)=>K.model));for(let K of z.models){let j=B4("glm",K.model);K.context1m=j!=null&&j>=1e6||void 0}z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){B(`glm refreshModels MISS: ${H?.message??H}`),z.models=[],z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let W={...u0(H)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_AUTH_TOKEN=Q,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(H){return y8("glm",H)},async verifyModel(H){return P7(J,{Authorization:`Bearer ${Q}`},H)},async readUsage(){return DJ(await H7(J,Q))}};return z},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:H9(Z.length===2?Z[0]:t2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await r2($.base_url??t2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!F2(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var gH=R(()=>{z0();P4();D0({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 p8(),!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}})});import{homedir as HU}from"node:os";function D7($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function q7($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!D7($))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 pH($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function cH($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=pH(x9(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&&pH(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 WU($){if(!D7($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!D7($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[q7(Z.five_hour,"fiveHour","5h 窗口"),q7(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(q7(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(!D7(Y)||typeof Y.display_name!=="string"||!Y.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Y.display_name.trim();J.push(q7(Y,`modelWeekly:${V}`,`${V} 周额度`)),Q=!0}}if(!Q)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function lH($){return GU.readStale("claude-subscription",()=>KU($))}async function KU($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (_4(),_Z)),J=new Z({workDir:HU(),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,z)=>{Q=setTimeout(()=>z(Error(`Claude 订阅额度查询超时(${mH/1000}s)`)),mH)})]);return WU(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":V2(Z)?"rate_limited":"network",windows:[],reason:J}}}var mH=30000,GU;var UJ=R(()=>{h();XZ();Q1();GU=new Z$});function BU(){let $=Object.fromEntries(k8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function jU($){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 uH=R(()=>{_0();h();z0();P4();UJ();V1();D0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=BU(),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:jU,spawnEnv(X){return{...u0(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 p8({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id});if(!X.length)throw Error("Claude Code 订阅模型目录为空");let z=[...r($.custom_models),...r($.models)];if(J&&!X.some((H)=>H.model===J)&&!z.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let H=X.find((G)=>G.model===(J??X[0].model));if(!R0($.effort)||H&&!H.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(H)H.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let z=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${z}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:z}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Y??=lH({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Y=void 0}),Y}};return V}})});function iH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function _U($){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 LU($){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 PU($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function nH($,Z){return(await MJ(new URL($).origin,Z)).map((Q)=>({model:Q,display:Q,efforts:L4,defaultEffort:"high"}))}async function MJ($,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 v$(`${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 OJ($,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 DU.readStale(L$("deepseek",J,Z),()=>FU(J,Z))}async function FU($,Z){try{let J=await X0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(qU)});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:y$(J.headers)};let Q=await J.json(),V=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",z=V?.total_balance;if(!X||typeof z!=="string"&&typeof z!=="number"||String(z).trim()===""||!Number.isFinite(Number(z)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(z),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var dH="https://api.deepseek.com/anthropic",qU=1e4,DU;var AJ=R(()=>{p0();z0();P4();b9();qJ();h();s2();Q1();DU=new Z$;D0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||dH,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,V=$.model?.trim()||void 0,X=LU($.slots),z={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(!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await nH(J,Q),W=[...new Set([...iH($.models),...iH($.custom_models)])].filter((K)=>!H.some((j)=>j.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:L4,defaultEffort:"high",origin:"custom"}));if(z.models=[...H,...W],!V)z.defaultModel=_U(z.models.map((K)=>K.model));for(let K of z.models){let j=B4("deepseek",K.model);K.context1m=j!=null&&j>=1e6||void 0}z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){B(`deepseek refreshModels MISS: ${H?.message??H}`),z.models=[],z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H?.message??String(H)}}},spawnEnv(H){let W={...u0(H)};if(W.ANTHROPIC_BASE_URL=J,W.ANTHROPIC_API_KEY=Q,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(H){return y8("deepseek",H)},async verifyModel(H){return P7(J,{"x-api-key":Q},H)},async readUsage(){if(!Q)return{kind:"balance",state:"no_credentials",windows:[]};return OJ(J,Q)}};return z},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 nH($.base_url??dH,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!PU(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function M2($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var NJ;var aH=R(()=>{NJ=[{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 O2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function TJ($){return $ instanceof Error?$.message:String($)}function sH($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function b4($){return $.replace(/\[1m\]$/,"")}function k4($){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 OU($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Q=await X0(`${k4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(UU)});if(!Q.ok){let Y=await Q.text(),V="";if(Y.trim().startsWith("{"))try{let X=JSON.parse(Y);if(O2(X)&&O2(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new F7(Q.status,V.replaceAll(Z,"[redacted]"),y$(Q.headers))}return Q.json()}async function tH($,Z){let J=await v$(`${k4($)}/v1/models/user`,Z,"OpenRouter models"),Q=[],Y=new Set;for(let V of J){if(!O2(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!O2(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(M2(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Y.has(V.id))continue;let X=O2(V.reasoning)?V.reasoning:void 0,z=X?.supported_efforts,H=z===null||z===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(z)?[...new Set(z.filter((j)=>j!=="default"&&R0(j)))]:["default"],G=NJ.find((j)=>j.model===V.id),W=G?H.includes(G.effort)?G.effort:null:H[0]==="default"?"default":R0(X?.default_effort)&&H.includes(X.default_effort)?X.default_effort:null,K=B4("openrouter",V.id);Q.push({model:V.id,display:V.name,efforts:H,defaultEffort:W,context1m:K!==void 0&&K>=1e6||void 0}),Y.add(V.id)}if(!Q.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Q}function rH($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function AU($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return MU.readStale(L$("openrouter",k4($),Z),()=>NU($,Z))}async function NU($,Z){try{let J=await OU($,Z,"credits");if(!O2(J)||!O2(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Q,total_usage:Y}=J.data;if(!rH(Q)||!rH(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=TJ(J);return B(`openrouter readUsage MISS: ${Q}`),{kind:"balance",state:J instanceof F7&&J.status===429?"rate_limited":"network",windows:[],reason:Q,...J instanceof F7?{retryAfterMs:J.retryAfterMs}:{}}}}var oH="https://openrouter.ai/api",UU=1e4,MU,RJ,F7;var eH=R(()=>{p0();_0();z0();b9();h();aH();s2();Q1();MU=new Z$,RJ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};F7=class F7 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};D0({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()||oH,V=$.model?.trim()||"",X=$.models===void 0?NJ.map((H)=>H.model):sH($.models),z={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Q,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(H){if(M2(H))throw Error(`OpenRouter 已排除此厂商或自动路由: ${H}`);if(!H.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(H){let G=z.modelSelection.availableModels.find((W)=>b4(W.model)===b4(H));if(!G||G.unavailableReason||!G.efforts.length)return"model-unavailable";return G.efforts.includes("default")?"effort-unset":"effort-level"},modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},async refreshModels(){if(z.models=[],z.modelSelection.availableModels=[],!z.enabled){z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{let H=await tH(Y,Q),G=H.find((K)=>K.model===b4(V));if(V&&!G)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!R0($.effort)||!G.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);G.defaultEffort=$.effort}let W=X.map((K)=>{let j=H.find((_)=>_.model===b4(K));if(!j)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:M2(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{...j,model:K}});z.models=W,z.modelSelection.availableModels=H,z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){let G=TJ(H);B(`openrouter refreshModels MISS: ${G}`),z.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G}}},spawnEnv(H,G){if(!Q)throw Error("OpenRouter API key missing");let W=G||V;if(!W)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(M2(W))throw Error(`OpenRouter 已排除此厂商或自动路由: ${W}`);let K=u0(H);K.ANTHROPIC_BASE_URL=k4(Y),K.ANTHROPIC_AUTH_TOKEN=Q,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 j of Object.values(RJ))K[j]=W;for(let j of sH($.slots)){let _=j.indexOf("="),D=j.slice(0,_).trim(),P=j.slice(_+1).trim();if(_<1||!Object.hasOwn(RJ,D)||!P)throw Error(`OpenRouter slots 无效: ${j}`);if(M2(P)||!z.modelSelection.availableModels.some((L)=>!L.unavailableReason&&b4(L.model)===b4(P)))throw Error(`OpenRouter slot 模型不在账号目录中: ${P}`);if(z.modelEnvironmentRevision(P)!==z.modelEnvironmentRevision(W))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${P}`);K[RJ[D]]=P}return K},resolveSpawnModel(H){if(M2(H))throw Error(`OpenRouter 已排除此厂商或自动路由: ${H}`);return H||void 0},readUsage(){return AU(Y,Q)}};return z},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:k4(Z[0])}:{}}}}catch(J){return{error:TJ(J)}}},async validate($){await tH($.base_url??oH,$.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=k4(Z);if(new URL(Q).hostname!=="openrouter.ai")return null;return{base_url:Q,api_key:J}}catch{return null}}}})});function TU($){return $.trim().replace(/\[1m\]$/,"").toLowerCase().split("/").at(-1)??""}function ZG($,Z="packy"){return RU[Z].includes(TU($))}var $G,RU;var JG=R(()=>{$G=["minimax-m3","claude-opus-5","claude-fable-5-1","qwen3.8-max-0902"],RU={packy:$G,"packy-secondary":$G,"packy-codex":["kimi-k3","grok-4.6"]}});function xJ($){return $.replace(/\[1m\]$/,"")==="gemini-3.8-flash"}function EU($,Z,J){let Q=Z==="claude"?E9:Y2,Y=$.reasoning?.supported_efforts;if(Y!==void 0&&(!Array.isArray(Y)||!Y.length||!Y.every((H)=>typeof H==="string")))throw Error(`PackyAPI ${$.id} 的推理档位声明无效`);let V=Y===void 0?[...Q]:Q.filter((H)=>Y.includes(H));if(!V.length)throw Error(`PackyAPI ${$.id} 未声明当前 Agent 可用的推理档位`);let X=J.effort?.trim(),z=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 z==="string"&&V.includes(z)?z:null}}var EJ="LODESTAR_PACKY_API_KEY",QG,YG;var VG=R(()=>{_0();J1();_J();JG();V1();h();Q1();z0();QG={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"};YG=[{id:"packy",agent:"claude",display:"PackyAPI"},{id:"packy-secondary",agent:"claude",display:"PackyAPI · 令牌2"},{id:"packy-codex",agent:"codex",display:"PackyAPI"}];for(let $ of YG){let{id:Z,agent:J,display:Q}=$,Y=J==="claude"?"anthropic":"openai-response",V=(X)=>X.protocols.includes(Y)||J==="claude"&&xJ(X.id);D0({kind:Z,configSectionId:Z,build(X){let z=X.api_key?.trim()||X.auth_token?.trim()||"",H=c$(X.base_url?.trim()||U2),G=X.management_url?.trim()?c$(X.management_url):S4(H),W=X.management_token?.trim()||"",K=X.management_user_id?.trim()||"",j=!!(W||K||X.management_url?.trim()||X.billing_source?.trim()),_=X.model?.trim(),D=X.models===void 0?void 0:r(X.models),P=new Set([...r(X.custom_models),...D??[]]),L=(M)=>ZG(M,Z),F=[],U=(M)=>{let O=F.find((T)=>T.id===M);if(O&&!V(O)&&!P.has(M))throw Error(`PackyAPI ${M} 未声明 ${Y};确认兼容后可显式补录`)},A={id:Z,kind:Z,agent:J,display:X.display?.trim()||Q,enabled:!!z&&X.enabled!==!1,models:[],defaultModel:_??"",modelSelection:{mode:"allowlist",modelIds:D??[],availableModels:[]},...j?{usageAccount:{id:L$("packy-account",G,K),label:"PackyAPI"}}:{},modelCatalogState:{status:z&&X.enabled!==!1?"idle":"disabled",updatedAt:Date.now()},...J==="claude"?{modelEnvironmentRevision(M){return xJ(M)?JSON.stringify(QG):"native-retries"}}:{},...J==="codex"?{codexApiProvider:{id:"packy",name:"PackyAPI",baseUrl:`${H}/v1`,envKey:EJ}}:{},async refreshModels(){if(A.models=[],F=[],!A.enabled){A.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}A.modelCatalogState={status:"loading",updatedAt:null};try{F=await BJ(H,z);let M=F.filter((E)=>V(E)||P.has(E.id));if(!M.length&&!P.size)throw Error(`PackyAPI 此令牌没有声明支持 ${Y} 的模型,请检查分组和模型限制`);let O=M.map((E)=>({...EU(E,J,X),...!E.protocols.includes(Y)&&P.has(E.id)?{origin:"custom"}:{}}));for(let E of P){if(O.some((f)=>f.model.toLowerCase()===E.toLowerCase()))continue;O.push({model:E,display:E,origin:"custom",...B2(A,X)})}if(_&&!O.some((E)=>E.model===_)){if(F.find((f)=>f.id===_))throw Error(`PackyAPI ${_} 未声明 ${Y},确认兼容后请显式补录`);if(!P.has(_))throw Error(`PackyAPI 默认模型不在目录中且未补录: ${_}`)}let T=D??O.filter((E)=>E.origin==="custom"||L(E.model)).map((E)=>E.model);if(D===void 0&&_&&!T.some((E)=>E.toLowerCase()===_.toLowerCase()))T.unshift(_);let k=T.map((E)=>O.find((f)=>f.model===E)??{model:E,display:E,efforts:[],defaultEffort:null,unavailableReason:"账号目录未返回该模型"});A.modelSelection.availableModels=O,A.models=k,A.modelSelection.modelIds=k.map((E)=>E.model),A.defaultModel=_??k.find((E)=>!E.unavailableReason)?.model??[...P][0]??"",A.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(M){A.models=[],F=[];let O=c0(M,[z]);B(`${Z} refreshModels MISS: ${O}`),A.modelCatalogState={status:"failed",updatedAt:Date.now(),error:O}}},resolveSpawnModel(M){return U(M),M},spawnEnv(M,O){if(!z)throw Error("PackyAPI API key missing");let T=O||A.defaultModel;if(!T)throw Error("PackyAPI 尚未选择模型");U(T);let k=u0(M);if(delete k[EJ],J==="codex"){for(let f 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 k[f];return k[EJ]=z,k}if(k.ANTHROPIC_BASE_URL=H,k.ANTHROPIC_AUTH_TOKEN=z,k.ANTHROPIC_API_KEY="",k.CLAUDE_CODE_NO_MODEL_FALLBACK="1",xJ(T))Object.assign(k,QG);k.ANTHROPIC_MODEL=T,k.ANTHROPIC_SMALL_FAST_MODEL=T,k.CLAUDE_CODE_SUBAGENT_MODEL=T;for(let f of["OPUS","SONNET","HAIKU","FABLE"])k[`ANTHROPIC_DEFAULT_${f}_MODEL`]=T;let E={opus:"OPUS",sonnet:"SONNET",haiku:"HAIKU",fable:"FABLE"};for(let f of r(X.slots)){let[d,S,g]=f.split("=");if(!d||!Object.hasOwn(E,d)||!S||g!==void 0)throw Error(`PackyAPI slots 无效: ${f}`);if(!R1(A).some((V0)=>V0.model===S))throw Error(`PackyAPI slot 模型不在当前来源: ${S}`);U(S),k[`ANTHROPIC_DEFAULT_${E[d]}_MODEL`]=S}return k},readUsage(){return j?jJ(G,W,K):vH(H,z)}};return A},setup:{commandSuffix:Z,hint:()=>`发送 \`${Z}-setup [base_url] <api_key>\` 配置${Q}。${Z==="packy-codex"?"与 PackyAPI 主账号共用凭据。":""}`,parseArgs(X){let z=X.trim().split(/\s+/).filter(Boolean);if(z.length<1||z.length>2||/^https?:\/\//i.test(z.at(-1)))return{error:`用法: ${Z}-setup [base_url] <api_key>`};try{return{config:{agent:J,api_key:z.at(-1),base_url:c$(z.length===2?z[0]:U2)}}}catch(H){return{error:c0(H,[z.at(-1)])}}},async validate(X){if(!(await BJ(X.base_url??U2,X.api_key??X.auth_token??"")).some(V)&&!r(X.custom_models).length&&!r(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 z=X.trim().split(/\s+/).filter(Boolean);if(z.length===2&&z[0]==="share"){if(!YG.some((W)=>W.id===z[1])||z[1]===Z)return{error:"请指定另一个已配置的 PackyAPI 来源:packy、packy-secondary 或 packy-codex"};return{config:{billing_source:z[1],management_token:"",management_user_id:"",management_url:""}}}if(z.length<2||z.length>3)return{error:`用法:${Z}-balance-setup [management_url] <user_id> <system_token>,或 ${Z}-balance-setup share <source_id>`};let H=z.at(-2),G=z.at(-1);if(!/^[1-9]\d*$/.test(H)||!Number.isSafeInteger(Number(H)))return{error:"用户 ID 必须是正整数"};try{return{config:{billing_source:"",management_token:G,management_user_id:H,management_url:z.length===3?c$(z[0]):""}}}catch(W){return{error:c0(W,[G])}}},async validate(X){let z=X.management_url||S4(X.base_url||U2),H=await jJ(z,X.management_token||"",X.management_user_id||"",!0);if(H.state!=="ok")throw Error(H.reason||"PackyAPI 真实账户余额查询失败")}}}})}});var XG=1;import{EventEmitter as xU}from"node:events";import{createRequire as SU}from"node:module";import{createHash as CU,randomUUID as bU}from"node:crypto";import{createInterface as kU}from"node:readline";import{dirname as wU,join as H1,isAbsolute as vU}from"node:path";import{fileURLToPath as SJ}from"node:url";import{tmpdir as yU}from"node:os";import{existsSync as zG,mkdirSync as HG,mkdtempSync as fU,readFileSync as o9,renameSync as hU,writeFileSync as GG,rmSync as CJ}from"node:fs";import IU from"cross-spawn";function gU($){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 mU($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=o9(H1($,".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,z=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(!z)throw Error(`DSH does not support MCP transport ${X.type} for ${Y}`);return{id:`lodestar-mcp-${Y}`,name:"@deepseek-ai/dsh-mcp-client",config:{...z,failOnStartupError:!0}}})}async function w4($,Z,J={}){let Q=new U7($);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 U7;var s9=R(()=>{H0();Z4();h();U7=class U7 extends xU{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!vU($.cwd))throw Error("DSH requires an absolute workspace");let Z=X8("dsh"),Q=SU(H1(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Y=JSON.parse(o9(Q,"utf8"));B(`dsh runtime: ${Y.version} (${Z})`);let V=gU($.env),X=$.home??i2;HG(X,{recursive:!0,mode:448});let z=mU($.cwd,$.profile);this.launchDir=fU(H1(yU(),"lodestar-dsh-"));let H=import.meta.url.endsWith(".ts"),G=H?"dsh-bridge.ts":"dsh-bridge.js",W=o9(SJ(new URL(`./${G}`,import.meta.url))),K=H?o9(SJ(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),j=JSON.parse(o9(SJ(new URL("../package.json",import.meta.url)),"utf8")),_=Buffer.from(JSON.stringify({name:j.name,version:j.version,type:"module",private:!0})),D=CU("sha256").update(W).update(K).update(_).digest("hex").slice(0,20),P=H1(Z,".lodestar-bridges",D);HG(P,{recursive:!0});let L=H1(P,G),F=(E,f)=>{if(zG(E))return;let d=`${E}.${bU()}.tmp`;try{GG(d,f),hU(d,E)}finally{if(zG(d))CJ(d)}};if(F(H1(P,"package.json"),_),H)F(H1(P,"dsh-protocol.ts"),K);F(L,W);let U=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((E)=>({id:E,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:L},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...z]},...V],A=H1(this.launchDir,"bridge.patch.yml");GG(A,JSON.stringify(U),{mode:384});let M=$.env.LODESTAR_DSH_NODE||"node",O=[H1(wU(Q),Y.bin.dsh),"--profile","sdk","--patch",A,...($.patches??[]).flatMap((E)=>["--patch",E])],T={...$.env};if(T.LODESTAR_AGENT_CAPABILITY&&T.LODESTAR_AGENT_URL)T.DSH_LODESTAR_AGENT_CONTEXT=JSON.stringify({baseUrl:T.LODESTAR_AGENT_URL,capability:T.LODESTAR_AGENT_CAPABILITY});for(let E of Object.keys(T))if(E.startsWith("LODESTAR_AGENT_"))delete T[E];try{this.child=IU(M,O,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...T,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(E){throw CJ(this.launchDir,{recursive:!0,force:!0}),E}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(E)=>{this.stderr=(this.stderr+E).slice(-16384),B(`dsh stderr: ${E.trimEnd()}`)}),this.child.stdin.on("error",(E)=>this.transportFailure(E));let k=kU({input:this.child.stdout,crlfDelay:1/0});k.on("line",(E)=>this.receive(E)),this.exitTask=new Promise((E)=>{this.child.once("error",(f)=>this.transportFailure(f)),this.child.once("close",(f,d)=>{this.exited=!0,k.close();let S=Error(`DSH exited code=${f} signal=${d}
118
+ ${this.stderr}`);this.rejectPending(S),CJ(this.launchDir,{recursive:!0,force:!0}),E(),this.emit("exit",{code:f,signal:d,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==XG||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
118
119
  ${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})+`
119
- `,(z)=>{if(z)this.transportFailure(z)})})}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}`)}}});var QG=N(()=>{X0();_0();o9();H0();OJ();V1();D0({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=O9(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 w4({cwd:i2,env:Q.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...r($.models),...r($.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(O0)||!O0(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:z,efforts:H,defaultEffort:G,isCustom:W})=>{let K=$.effort?.trim();if(K&&(!O0(K)||!H.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:z,efforts:H,defaultEffort:K?K:G,origin:W?"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 R1(Q).find((V)=>V.model===Y)?.model},readUsage(){return Z?MJ(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 UJ($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function U7($){let Z=new URL($);if(!D2(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 YG($,Z){return(await v$(`${$}/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 VG=N(()=>{s2();f0();_0();X0();o9();H0();H7();DJ();V1();D0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=m.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Q=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Q&&D2(Q)?{api_key:J,base_url:U7(Q)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Q=U7($.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((X.modelSelection?.availableModels??X.models).map((z)=>z.model).sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(z){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let H=O9(z);H.LODESTAR_DSH_PROVIDER=Y,H.LODESTAR_DSH_GLM_API_KEY=J,H.LODESTAR_DSH_BASE_URL=Q,H.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel;let G=(X.modelSelection?.availableModels??X.models).map((W)=>W.model);if(V||G.length)H.LODESTAR_DSH_MODELS=JSON.stringify(V??G);if($.bin)H.LODESTAR_DSH_NODE=$.bin;return H},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 z=await YG(Q,J),H=[...z];for(let W of[...r($.models),...r($.custom_models)])if(!H.some((K)=>K.model.toLowerCase()===W.toLowerCase()))H.push({model:W,display:W});if(V=H.map((W)=>W.model),!$.model?.trim()){let W=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...z].sort((K,j)=>W(j.model)-W(K.model))[0].model}let G=await w4({cwd:i2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=H.map((W)=>{let K=G.find((L)=>L.model===W.model),j=K2(X,$),_=K?K.efforts.filter(O0):j.efforts,D=$.effort?.trim()||K?.defaultEffort||j.defaultEffort;return{...W,display:K?.display??W.display,efforts:_,defaultEffort:O0(D)&&_.includes(D)?D:null,origin:z.some((L)=>L.model===W.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z instanceof Error?z.message:String(z)},z}},resolveSpawnModel(z){return R1(X).find((H)=>H.model===z&&!H.unavailableReason)?.model},async readUsage(){return J?qJ(await z7(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:U7(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 YG(U7($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var HG={};r$(HG,{tokenSourceSpawnRevision:()=>zG,buildTokenSourcesFromConfig:()=>s9});import{createHash as XG}from"node:crypto";function s9(){let $=WJ(),Z=Object.fromEntries(H2().flatMap((G)=>{let W=G.detect?.fromSettingsEnv($);return G.configSectionId&&W?[[G.configSectionId,W]]:[]})),J=i9(m.token_sources??{},Z),Q=new Map(d0().map((G)=>[G.id,G])),Y=H2().map((G)=>{let W=G.configSectionId?J[G.configSectionId]??{}:{},K=G.configSectionId?Z[G.configSectionId]??null:null,j=()=>{let _=w8(G.build(W,K),W);return _.spawnRevision=zG(G.kind,W,K),_};return{cfg:W,detected:K,create:j,initial:j()}}),V=Y.some(({initial:G})=>G.agent==="claude"&&G.enabled&&G.kind!=="claude-native"&&G.kind!=="claude-subscription"),X=Y.map(({cfg:G,detected:W,create:K,initial:j})=>{let _=()=>{let F=K();if(F.kind==="claude-native")F.enabled=!V,F.modelCatalogState={status:F.enabled?"idle":"disabled",updatedAt:Date.now()};return F},D=(F)=>{let{display:U,model:A,effort:M,models:O,hidden_models:R,custom_models:w,slots:T,default:f,...u}=F??{};return u},L=(F)=>XG("sha256").update(JSON.stringify(F,(U,A)=>A&&typeof A==="object"&&!Array.isArray(A)?Object.fromEntries(Object.entries(A).sort(([M],[O])=>M.localeCompare(O))):A)).digest("hex"),P=j.kind==="claude-native"?!V:void 0;return _Z(_,G,L([j.id,D(G),D(W),P]),L([G,W,P]),Q.get(j.id))});ZZ();for(let G of X)r5(G);for(let G of Q.values())if(!X.includes(G))w9(G);let H=X.find((G)=>G.enabled&&m.token_sources?.[G.id]?.default===!0)??X.find((G)=>G.enabled);if(H)$Z(H.id);return X.length}function zG($,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 XG("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var M7=N(()=>{f0();X0();H7();V1();n9();l8();p8();DJ();kH();hH();OJ();iH();rH();QG();VG()});function CJ($){let Z=new Map,J=$.map((K)=>{let j=K.fingerprint?Z.get(K.fingerprint):void 0;if(K.fingerprint&&!j)Z.set(K.fingerprint,K.account.name);return{...K,...j?{duplicateOf:j}:{}}}),Q=J.filter((K)=>!K.duplicateOf),V=(Q.length<=1||Q.every((K)=>K.fingerprint!==null))&&Q.every((K)=>K.usage.state==="ok"),X=Q.flatMap((K)=>K.usage.state==="ok"?[K.usage]:[]),z=X.map((K)=>{let j=c5(K);if(j.state==="exhausted")return!1;if(j.state==="miss")return null;if(j.state==="credits")return!0;return[K.fiveHour,K.weekly].filter((D)=>D!==null).length?!0:null}),H=V&&z.every((K)=>K!==null)?z.filter(Boolean).length:null,G=V&&X.every((K)=>K.resetCredits!=null)?X.reduce((K,j)=>K+j.resetCredits,0):null,W=["fiveHour","weekly"].map((K)=>{let j=X.map((D)=>D[K]).filter((D)=>D!==null),_=V&&j.every((D)=>D.percent!==null&&D.percent>=0&&D.percent<=100);return{kind:K,count:j.length,remaining:_?j.reduce((D,L)=>D+(100-L.percent)/100,0):null}}).filter((K)=>K.count||!V);return{entries:J,complete:V,available:H,resetCredits:G,windows:W}}async function GG($){return{...$,entries:$.entries.map((Z)=>{let J=lX(Z.account.id);return{...Z,email:J?.email??null,emailError:J?.error??(!J?"账号信息缓存尚未就绪,后台刷新中":void 0)}})}}async function O7($){let Z=new Map,J=await Promise.all(y.list().map(async(Q)=>{let Y=null;try{Y=y.fingerprint(Q.id)}catch(H){return{account:Q,fingerprint:Y,usage:{state:"network",reason:`账号身份读取失败:${String(H)}`}}}let V=Y??Q.id,X=Z.get(V);if(!X)X=$?.id===Q.id?Promise.resolve($.usage):oX(Q.id),Z.set(V,X);let z=await X;if(z.state==="ok"&&z.accountFingerprint)Y=z.accountFingerprint;return{account:Q,usage:z,fingerprint:Y}}));return CJ(J)}var bJ=N(()=>{j0();J$();h();T8();J2()});import{createHash as WG,randomUUID as EU}from"node:crypto";function v4($,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 kJ($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function T$($){let Z=H$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function z$($){return!H$.has($)}function E$($,Z,J){H$.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,uncertainAdds:new Set,confirmedAdds:new Set,failedReplacements:new Set,onFailure:J,closing:!1})}function r9($){return H$.get($)?.elementCount??0}function KG($){let Z=H$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function y4($,Z){return H$.get($)?.deadElements.has(Z)??!1}function BG($,Z){let J=H$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function A7($){let Z=T$($);return Z.sequence+=1,Z.sequence}function wJ($,Z){$.deadElements.add(Z)}function jG($){return WG("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function kU($,Z,J){let Q=[...$.contentFingerprints].filter(([Y])=>Y!==Z).map(([,Y])=>Y);if(J&&Z!==b.footer)Q.push(J);return WG("sha256").update(Q.sort().join(`
120
- `)).digest("hex")}async function t9($,Z,J,Q){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:EU()}:{}}):void 0,V=`cardkit ${$} ${Z}`;return s1(V,async()=>{let X=await m$(),z=AbortSignal.timeout(SU),H;try{return H=await V0(`${xU}${Z}`,{method:$,headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:z}),(await B$(H,V))?.data}catch(G){if(z.aborted&&z.reason?.name==="TimeoutError")G=z.reason;if(H&&G instanceof y0)Object.assign(G,{httpStatus:H.status});throw Q?.(G),G}},{api:"cardkit"})}function vJ($){return $ instanceof y0&&($.code===200770||$.code==="200770")}function _G($){if(vJ($))return!1;if($ instanceof y0){if($.status===429||$.code===99991400||$.code===230020)return!1;if($.status!==void 0&&$.status>=200&&$.status<300&&$.code===void 0)return!0}return J8($,{api:"cardkit"})}async function N7($,Z,J,Q){let Y=!1;try{await t9(Z,J,{...Q,sequence:A7($)},(V)=>{if(_G(V))Y=!0})}catch(V){if(!Y||!vJ(V))throw V;B(`cardkit confirm ${Z} ${J}: ${V}; retrying same state with new UUID and sequence`),await t9(Z,J,{...Q,sequence:A7($)})}}async function PG($,Z,J,Q){let Y=J.element_id,V=!1;try{await t9("POST",`/cards/${$}/elements`,{type:Q.type??"append",...Q.targetElementId?{target_element_id:Q.targetElementId}:{},elements:JSON.stringify([J]),sequence:A7($)},(X)=>{if(_G(X)){if(V=!0,Y)Z.uncertainAdds.add(Y)}})}catch(X){let z=X,H=Y&&Z.uncertainAdds.has(Y)&&kJ(z?.code,z);if(!Y||!(H||V&&vJ(X)))throw X;B(`cardkit reconcile uncertain add ${$} element=${Y}: ${X}; confirming latest content with PUT`),await N7($,"PUT",`/cards/${$}/elements/${Y}`,{element:JSON.stringify(J)})}if(!Y||!Z.confirmedAdds.has(Y))Z.elementCount++;if(Y)Z.confirmedAdds.add(Y),Z.uncertainAdds.delete(Y)}function wU($){return new Promise((Z)=>setTimeout(Z,$))}function vU($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function yU($){await N7($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}})})}async function R7($,Z,J,Q,Y=!1,V={}){let X=(z)=>{let H=typeof z==="object"&&z!==null?z:null,G={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:H?.code,httpStatus:H?.httpStatus,logId:H?.logId,message:z instanceof Error?z.message:String(z),apiMessage:H?.apiMessage};if(v4(G.code,G))G.capacityFingerprint=kU(T$($),V.elementId,V.contentFingerprint);try{if(!Y||Y==="non-capacity"&&v4(G.code,G))T$($).onFailure?.(G.code,G)}catch(W){B(`cardkit failure callback ${$}: ${W}`)}try{Q?.(G)}catch(W){B(`cardkit per-call failure callback ${$}: ${W}`)}};try{await J();return}catch(z){if(!vU(z)){B(`cardkit ${Z} ${$}: ${z}`),X(z);return}B(`cardkit ${Z} ${$}: streaming closed (code=${z.code}) — reopening`)}try{await yU($)}catch(z){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${z}`),X(z);return}try{await J()}catch(z){B(`cardkit ${Z} ${$} retry-after-reopen: ${z}`),X(z)}}function fU($){return typeof $==="object"&&$!==null&&$.code===200740}async function l$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:CU,Q=null;for(let Y=0;Y<J.length;Y++){let V=J[Y]??0;if(V>0)await wU(V);try{let X=await t9("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,!fU(X)||Y===J.length-1)throw X;let z=J[Y+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${z}ms`)}}throw Q}async function v1($){let Z=H$.get($);if(!Z)return;await Z.queue}function T0($,Z,J={},Q,Y="all"){if(z$($))return Promise.resolve();let V=T$($);if(V.closing)return Promise.resolve();let X=S1(Z),z=X.element_id,H=jG(X),G=()=>{if(!z)return;wJ(V,z),V.failedAdds.set(z,J)};return V.queue=V.queue.then(()=>R7($,"addElement",async()=>{if(await PG($,V,X,J),z!==b.footer)V.contentFingerprints.set(z??`#${V.sequence}`,H);if(z)V.deadElements.delete(z),V.failedAdds.delete(z),V.failedReplacements.delete(z)},(W)=>{G(),Q?.(W.code,W)},Y==="capacity"?"non-capacity":!1,{elementId:z,targetElementId:J.targetElementId,contentFingerprint:H})),V.queue}function F0($,Z,J,Q,Y=!0){if(z$($))return Promise.resolve();let V=T$($);if(V.closing)return Promise.resolve();let X=S1(J),z=jG(X),H=()=>{wJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>R7($,`replaceElement ${Z}`,async()=>{let G=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!G&&!V.failedReplacements.has(Z))return;if(G)await PG($,V,X,G);else await N7($,"PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(X)});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.uncertainAdds.delete(Z),V.failedReplacements.delete(Z),Z!==b.footer)V.contentFingerprints.set(Z,z)},(G)=>{if(Y)H();Q?.(G.code,G)},!Y,{elementId:Z,contentFingerprint:z})),V.queue}async function B0($,Z,J,Q={}){if(z$($))return!1;let Y=T$($);if(Y.closing)return!1;let V=!1;return await F0($,Z,J,(X,z)=>{if(V=!0,z)Q.onFailure?.(z)},Q.notifyCardFailure!==!1),!V&&!Y.deadElements.has(Z)}async function LG($,Z,J){if(z$($))return{landed:!1};let Q=T$($);if(Q.closing)return{landed:!1};let Y;return await F0($,Z,J,(V,X)=>{Y=X}),{landed:!Y&&!Q.deadElements.has(Z),...Y?{failure:Y}:{}}}async function A2($,Z,J={}){let Q=await f4($,Z,J);if(Q.failure)J.onFailure?.(Q.failure);return Q.landed}async function f4($,Z,J={}){if(z$($))return{landed:!1};let Q=T$($);if(Q.closing)return{landed:!1};let Y=Z.element_id,V;return await T0($,Z,J,(X,z)=>{V=z}),{landed:!V&&!(Y&&Q.deadElements.has(Y)),...V?{failure:V}:{}}}function hU($,Z,J){if(z$($))return Promise.resolve();let Q=T$($);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(()=>R7($,`deleteElement ${Z}`,async()=>{if(Y())return;let V=A7($);await t9("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Q.elementCount=Math.max(0,Q.elementCount-1),Q.contentFingerprints.delete(Z),Q.failedAdds.delete(Z),Q.uncertainAdds.delete(Z),Q.confirmedAdds.delete(Z),Q.failedReplacements.delete(Z),wJ(Q,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Q.queue}async function qG($,Z,J){if(z$($))return!1;let Q=T$($);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 hU($,Z,(V,X)=>{if(Y=!0,X)J?.(X)}),!Y&&Q.deadElements.has(Z)}function h4($,Z){if(z$($)||H$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=O2.get($);if(!Q)Q={latest:J,lastSent:"",timer:null,inFlight:!1},O2.set($,Q);else{if(Q.latest===J)return;Q.latest=J}DG($,Q)}function DG($,Z){if(Z.timer||Z.inFlight||Z.latest===Z.lastSent)return;Z.timer=setTimeout(()=>{if(O2.get($)!==Z)return;if(Z.timer=null,z$($)||H$.get($)?.closing){O2.delete($);return}if(Z.latest===Z.lastSent)return;let J=Z.latest;Z.inFlight=!0,k0($,{config:{summary:{content:J}}}).then((Q)=>{if(O2.get($)!==Z)return;if(Z.inFlight=!1,Q)Z.lastSent=J;if(Z.latest!==J&&!z$($)&&!H$.get($)?.closing)DG($,Z)})},bU)}function a0($){let Z=O2.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;O2.delete($)}function T7($,Z){return k0($,Z).then(()=>{})}async function k0($,Z,J){if(z$($))return!1;let Q=T$($);if(Q.closing)return!1;let Y=!1,V=!1;return Q.queue=Q.queue.then(()=>R7($,"patchSettings",async()=>{if(z$($))return;await N7($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z)}),Y=!0},(X)=>{V=!0,J?.(X)},!0)),await Q.queue,Y&&!V&&!z$($)}async function q$($){let Z=H$.get($);if(!Z){a0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,a0($),await Z.queue,H$.delete($)}var xU="https://open.feishu.cn/open-apis/cardkit/v1",SU=15000,CU,H$,O2,bU=1500;var G1=N(()=>{p0();$0();o2();h();h0();CU=[0,250,750,1500];H$=new Map,O2=new Map});function W1($){if(!$)return"积分 MISS";if(e1($)==="empty")return null;if($.unlimited)return"积分 无限";if($.balance===null)return"积分 MISS";return`积分 ${$.balance.toLocaleString("en-US",{maximumFractionDigits:20})}`}function u$($){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 FG($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(H)=>`&#${H.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",z=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${u$($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Y)}%${Q}**
121
- <font color='${X}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${z}</font>`,text_size:"notation"}]}var I4=()=>{};var AG={};r$(AG,{codexAccountSummary:()=>e9,codexAccountPanel:()=>$3,codexAccountCard:()=>n$,CODEX_ACCOUNTS_PAGE_SIZE:()=>E7});function i$($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function UG($){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 e9($){let[Z,J]=OG[$.phase],Q=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Q?`${Q} · `:""}${$.title??J}`}function n$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:e9($)}},body:{elements:[$3($)]}}}function $3($){let[,,Z]=OG[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Q=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(U0(["连接","授权","就绪"].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(UG([[d$("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[U0(`[**打开授权页 ↗**](${Q.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),d$("登录账号,输入左侧验证码")]]))}if($.current)J.push(UG([[d$("当前使用"),U0(`**${i$($.current)}**`)],...$.selected&&$.selected!==$.current?[[d$("下次启动"),U0(`**${i$($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(U0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Q)=>i$(Q)).join(" · ")));if($.message)J.push(U0(i$($.message)));if($.resetUsage){let Q=$.resetUsage;if(J.push(U0(`**重置卡** ${Q.state==="ok"&&Q.resetCredits!=null?`${Q.resetCredits} 次可用`:"MISS"}`)),Q.state==="ok"){let Y=W1(Q.credits);if(Y)J.push(U0(Y));for(let[V,X]of[[Q.fiveHour,"5h"],[Q.weekly,"周"]])if(V)J.push(...FG(V,X))}else J.push(U0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...IU($));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:[U0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
122
- `)),d$("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(d$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[U0(i$($.details))]});return{tag:"collapsible_panel",element_id:b.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:e9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:$.phase==="accounts"?"8px":"12px",...$.phase==="accounts"?{vertical_spacing:"8px"}:{},elements:J}}function MG($,Z){let J=$?.percent;if(J==null||!Number.isFinite(J)||J<0||J>100)return U0(`${Z} MISS`);let Q=Math.round(J/100*6),Y=J>=100?"red":J>=80?"orange":"green",V=$.unreportedFull?"满窗":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?u$($.resetsAt):"MISS";return U0(`${Z} <font color='${Y}'>${"▰".repeat(Q)}${"▱".repeat(6-Q)}</font> ${Math.round(J)}% <font color='grey'>「${V}」</font>`)}function IU($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/E7)),Q=$.page??1;if(!Number.isInteger(Q)||Q<1||Q>J)throw Error(`页码应为 1–${J}`);let Y=[],V=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort(U8)??[],X=new Map(V.map((H,G)=>[H.account.id,G+1])),z=Z.entries.slice().sort((H,G)=>(X.get(H.account.id)??1/0)-(X.get(G.account.id)??1/0));for(let H of z.slice((Q-1)*E7,Q*E7)){let G=H.usage,W=[],K=$.scheduling?.candidates.find((P)=>P.account.id===H.account.id),j=X.get(H.account.id),_=H.duplicateOf?"重复":K?.state==="ready"?K.funding==="credits"?"积分":K.priority==="expiring"?"临期优先":`${K.score.toPrecision(3)}/h`:"MISS";if(Y.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`#${j??"—"}·${H.account.name}「${_}」 · 重置 ${G.state==="ok"?G.resetCredits??"MISS":"MISS"}`},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"2px",elements:W}),W.push(d$(`邮箱:${H.email??"MISS"}`)),H.emailError)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"邮箱查询错误"}},elements:[U0(i$(H.emailError))]});if(H.duplicateOf){W.push(d$(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}if(K&&K.state!=="ready"){if(W.push(d$(K.state==="exhausted"?"⏳ 暂不可用":K.state==="excluded"?"Ultra 自动排除 Plus":K.state==="waiting"?`⏳ 周余量 ${K.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),K.reason&&G.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[U0(i$(K.reason))]})}if(G.state!=="ok"){if(W.push(U0(G.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),G.state==="network"&&G.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[U0(i$(G.reason))]});continue}if(W.push(MG(G.weekly,"周")),G.fiveHour)W.push(MG(G.fiveHour,"5h"));let D=W1(G.credits);if(D)W.push(U0(D));let L=$.activationErrors?.[H.account.id];if(L)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"后台激活 MISS"}},elements:[U0(i$(L))]})}if(J>1)Y.push(d$(`${Q}/${J} 页 · ${Q<J?`下一页 codex-accounts ${Q+1}`:"首页 codex-accounts"}`));return Y}var E7=4,OG,U0=($)=>({tag:"markdown",content:$}),d$=($)=>({tag:"markdown",content:`<font color='grey'>${i$($)}</font>`,text_size:"notation"});var g4=N(()=>{h0();I4();J2();OG={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"]}});class m4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=gU){let Q,Y=await J.sendCard($,n$(Z,!0),(X)=>{Q=X});if(!Y)throw Error(`Codex 账号卡片发送失败:${v(Q)}`);let V=await J.convertMessageToCard(Y);return J.recordCardCreated(V,1),new m4(V,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=$3($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=$3($);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,Y,V=await this.deps.replaceElementChecked(this.cardId,b.codexAccountPanel,Z,{notifyCardFailure:!1,onFailure:(z)=>{Q=z}}),X=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:e9($)}}},(z)=>{Y=z});if(!V||!X)throw Error(`Codex 账号卡片更新失败:内容 ${V?"OK":v(Q)},状态 ${X?"OK":v(Y)}`);if(J)await this.deps.dispose(this.cardId)}}var gU;var NG=N(()=>{$0();G1();h0();g4();gU={sendCard:i,convertMessageToCard:l$,recordCardCreated:E$,replaceElementChecked:B0,patchSettingsChecked:k0,dispose:q$}});var fJ={};r$(fJ,{settleCodexAccountCards:()=>yJ,runCodexNamedHi:()=>pU,runCodexAccountCommand:()=>cU});import{createHash as mU}from"node:crypto";function Z3($,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 RG($,Z){let J;if(!await i($.chatId,n$(Z3(Z)),(Q)=>{J=Q}))throw Error(`Codex 错误卡片发送失败
123
- ${v(J)}`)}async function pU($,Z){let J=await m4.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(Z3(Q,Z))}}async function yJ(){let Z=(await Promise.allSettled([...R2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function cU($,Z,J,Q,Y){if(Z==="reset"){await uU($,J,Y);return}let V={chatId:$.chatId,userOpenId:Q};if(Z==="login-cancel"){try{let G=q2.pending(V);if(!J&&G.length!==1)throw Error(G.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?y.find(J).id:G[0];await q2.cancel(W,V),await R2.get(W)}catch(G){await RG($,G)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,z=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),H=await m4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号邮箱与额度…":z?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let _=y.find(J);if(R2.has(_.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:D}=y.remove(_.id);wz(C0("codex-sub"),_.id),f$(_.id),await H.finish({phase:"deleted",name:_.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:D?`已清除 ${D} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let _=J?Number(J):1,D=$.codexAccountId(),L=G0("codex-sub",D),P=()=>$.currentProvider()==="codex"?$.currentModelLabel():L?.defaultModel,F=P(),U;if(!F)try{if(!L)throw Error("Codex 订阅来源尚未初始化");if(F=P(),!F)throw Error(L.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(R){U=`${y.get(D).name}:${R instanceof Error?R.message:String(R)}`}let A=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,M=F?await G2.choose({model:F,effort:A}):null,O=M?CJ(M.candidates.flatMap((R)=>{let T=(R.usage?.state==="network"||R.usage?.state==="rate_limited"?z2(R.account.id):null)??R.usage;return T?[{account:R.account,usage:T,fingerprint:R.identity.startsWith("record:")?null:R.identity}]:[]})):await O7();if(U)B(`codex-accounts: scheduling MISS: ${U}`);await H.finish({phase:"accounts",total:await GG(O),currentId:D,activationErrors:Object.fromEntries(O.entries.flatMap((R)=>{let w=R9.error(R.account.id);return w?[[R.account.id,w]]:[]})),...y.preferred($.sessionName)?{selectedId:y.selected($.sessionName)}:{},page:_,...M?{scheduling:{candidates:M.candidates,ultra:A==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:U,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");y.selectAuto($.sessionName),await H.finish({phase:"selected",name:"自动选择",current:y.get($.codexAccountId()).name,selected:"自动 · 临期 / 评分",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await H.finish({phase:"current",current:y.get($.codexAccountId()).name,selected:y.preferred($.sessionName)===null?"自动 · 临期 / 评分":y.get(y.selected($.sessionName)).name,hint:"周剩余份额 ÷(重置小时 − 5)· codex-auto"});return}let _=y.find(J),D=$.currentProvider()==="codex"?$.currentModelLabel():null,L=$.currentProvider()==="codex"?$.currentEffortLabel():null,P=y.get($.codexAccountId()).name;if($.currentProvider()==="codex")w1($.sessionName,"codex",D,L,"codex-sub");if(y.select($.sessionName,_.id),$.currentProvider()==="codex")$.selectedModel=D,$.selectedEffort=L,$.selectedTokenSourceId="codex-sub";await H.finish({phase:"selected",name:_.name,current:P,selected:_.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Q)throw Error("无法确认登录发起者");if(z)await MH(),await H.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let G=y.ensure(J);if(_8(G.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(R2.has(G.id))throw Error("登录结果正在更新,请稍等");let W=await q2.start(G.id,V);try{await H.update({phase:"waiting",flow:"login",name:G.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${G.name}`:""}`})}catch(_){throw await q2.cancel(G.id,V),_}let K=(async()=>{let _;try{_=await W.done}catch(D){await H.finish(Z3(D,G.name));return}s9(),G0("codex-sub",G.id),await H.finish({phase:"success",flow:"login",name:G.name,email:_.email,plan:_.planType,hint:`目录与额度正在后台刷新 · 优先使用:codex-account ${G.id==="default"?"default":G.name}`})})();R2.set(G.id,K);let j=()=>{if(R2.get(G.id)===K)R2.delete(G.id)};K.then(j,(_)=>{B(`codex-login: terminal card write failed: ${_}`),j()})}catch(G){B(`codex-${Z}: ${G}`),await H.finish(Z3(G,X))}}async function uU($,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(j$($.proc))}catch(G){B(`codex-reset: ${G}`),await RG($,G);return}let Y=await m4.open($.chatId,{phase:"checking",name:Q.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let G=mU("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await dX(Q.id,G)}catch(G){B(`codex-reset: ${G}`),await Y.finish(Z3(G,Q.name));return}let X=lU[V.outcome],H=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
124
- `);await Y.finish({...X,name:Q.name,resetUsage:V.usage,...H?{phase:"warning",details:H}:{},hint:"codex-accounts 查看各账号额度"})}var R2,lU;var x7=N(()=>{$0();j0();GJ();X0();M7();l8();bJ();k8();QZ();NG();g4();h();J$();R2=new Map;lU={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as dU}from"node:fs";function iU($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function nU($,Z){let J=[`[token_source.${$}]`],Q=(Y,V)=>{if(V!==void 0)J.push(`${Y} = "${iU(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(`
125
- `)}function aU($,Z){oU({[$]:Z})}function oU($){if(!Object.keys($).length)return;let Z=dU(v0,"utf8"),J=j9().token_sources,Q={};for(let[H,G]of Object.entries($)){let W=PJ(J,H,G);J={...J,...W},Object.assign(Q,W)}i9(J);let Y=new Set(Object.keys(Q).map((H)=>`[token_source.${H}]`)),V=Z.split(`
120
+ `,(z)=>{if(z)this.transportFailure(z)})})}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}`)}}});var WG=R(()=>{z0();_0();s9();H0();AJ();V1();D0({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=A9(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 w4({cwd:i2,env:Q.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...r($.models),...r($.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(O0)||!O0(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:z,efforts:H,defaultEffort:G,isCustom:W})=>{let K=$.effort?.trim();if(K&&(!O0(K)||!H.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:z,efforts:H,defaultEffort:K?K:G,origin:W?"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 R1(Q).find((V)=>V.model===Y)?.model},readUsage(){return Z?OJ(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 MJ($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function M7($){let Z=new URL($);if(!F2(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 KG($,Z){return(await v$(`${$}/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 BG=R(()=>{s2();f0();_0();z0();s9();H0();G7();FJ();V1();D0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=m.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Q=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Q&&F2(Q)?{api_key:J,base_url:M7(Q)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Q=M7($.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((X.modelSelection?.availableModels??X.models).map((z)=>z.model).sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(z){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let H=A9(z);H.LODESTAR_DSH_PROVIDER=Y,H.LODESTAR_DSH_GLM_API_KEY=J,H.LODESTAR_DSH_BASE_URL=Q,H.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel;let G=(X.modelSelection?.availableModels??X.models).map((W)=>W.model);if(V||G.length)H.LODESTAR_DSH_MODELS=JSON.stringify(V??G);if($.bin)H.LODESTAR_DSH_NODE=$.bin;return H},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 z=await KG(Q,J),H=[...z];for(let W of[...r($.models),...r($.custom_models)])if(!H.some((K)=>K.model.toLowerCase()===W.toLowerCase()))H.push({model:W,display:W});if(V=H.map((W)=>W.model),!$.model?.trim()){let W=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...z].sort((K,j)=>W(j.model)-W(K.model))[0].model}let G=await w4({cwd:i2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=H.map((W)=>{let K=G.find((P)=>P.model===W.model),j=B2(X,$),_=K?K.efforts.filter(O0):j.efforts,D=$.effort?.trim()||K?.defaultEffort||j.defaultEffort;return{...W,display:K?.display??W.display,efforts:_,defaultEffort:O0(D)&&_.includes(D)?D:null,origin:z.some((P)=>P.model===W.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z instanceof Error?z.message:String(z)},z}},resolveSpawnModel(z){return R1(X).find((H)=>H.model===z&&!H.unavailableReason)?.model},async readUsage(){return J?DJ(await H7(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:M7(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 KG(M7($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var LG={};r$(LG,{tokenSourceSpawnRevision:()=>_G,buildTokenSourcesFromConfig:()=>t9});import{createHash as jG}from"node:crypto";function t9(){let $=KJ(),Z=Object.fromEntries(G2().flatMap((G)=>{let W=G.detect?.fromSettingsEnv($);return G.configSectionId&&W?[[G.configSectionId,W]]:[]})),J=n9(m.token_sources??{},Z),Q=new Map(d0().map((G)=>[G.id,G])),Y=G2().map((G)=>{let W=G.configSectionId?J[G.configSectionId]??{}:{},K=G.configSectionId?Z[G.configSectionId]??null:null,j=()=>{let _=v8(G.build(W,K),W);return _.spawnRevision=_G(G.kind,W,K),_};return{cfg:W,detected:K,create:j,initial:j()}}),V=Y.some(({initial:G})=>G.agent==="claude"&&G.enabled&&G.kind!=="claude-native"&&G.kind!=="claude-subscription"),X=Y.map(({cfg:G,detected:W,create:K,initial:j})=>{let _=()=>{let F=K();if(F.kind==="claude-native")F.enabled=!V,F.modelCatalogState={status:F.enabled?"idle":"disabled",updatedAt:Date.now()};return F},D=(F)=>{let{display:U,model:A,effort:M,models:O,hidden_models:T,custom_models:k,slots:E,default:f,...d}=F??{};return d},P=(F)=>jG("sha256").update(JSON.stringify(F,(U,A)=>A&&typeof A==="object"&&!Array.isArray(A)?Object.fromEntries(Object.entries(A).sort(([M],[O])=>M.localeCompare(O))):A)).digest("hex"),L=j.kind==="claude-native"?!V:void 0;return LZ(_,G,P([j.id,D(G),D(W),L]),P([G,W,L]),Q.get(j.id))});JZ();for(let G of X)e5(G);for(let G of Q.values())if(!X.includes(G))v9(G);let H=X.find((G)=>G.enabled&&m.token_sources?.[G.id]?.default===!0)??X.find((G)=>G.enabled);if(H)ZZ(H.id);return X.length}function _G($,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 jG("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var O7=R(()=>{f0();z0();G7();V1();a9();u8();c8();FJ();gH();uH();AJ();eH();VG();WG();BG()});function bJ($){let Z=new Map,J=$.map((K)=>{let j=K.fingerprint?Z.get(K.fingerprint):void 0;if(K.fingerprint&&!j)Z.set(K.fingerprint,K.account.name);return{...K,...j?{duplicateOf:j}:{}}}),Q=J.filter((K)=>!K.duplicateOf),V=(Q.length<=1||Q.every((K)=>K.fingerprint!==null))&&Q.every((K)=>K.usage.state==="ok"),X=Q.flatMap((K)=>K.usage.state==="ok"?[K.usage]:[]),z=X.map((K)=>{let j=l5(K);if(j.state==="exhausted")return!1;if(j.state==="miss")return null;if(j.state==="credits")return!0;return[K.fiveHour,K.weekly].filter((D)=>D!==null).length?!0:null}),H=V&&z.every((K)=>K!==null)?z.filter(Boolean).length:null,G=V&&X.every((K)=>K.resetCredits!=null)?X.reduce((K,j)=>K+j.resetCredits,0):null,W=["fiveHour","weekly"].map((K)=>{let j=X.map((D)=>D[K]).filter((D)=>D!==null),_=V&&j.every((D)=>D.percent!==null&&D.percent>=0&&D.percent<=100);return{kind:K,count:j.length,remaining:_?j.reduce((D,P)=>D+(100-P.percent)/100,0):null}}).filter((K)=>K.count||!V);return{entries:J,complete:V,available:H,resetCredits:G,windows:W}}async function PG($){return{...$,entries:$.entries.map((Z)=>{let J=sX(Z.account.id);return{...Z,email:J?.email??null,emailError:J?.error??(!J?"账号信息缓存尚未就绪,后台刷新中":void 0)}})}}async function A7($){let Z=new Map,J=await Promise.all(v.list().map(async(Q)=>{let Y=null;try{Y=v.fingerprint(Q.id)}catch(H){return{account:Q,fingerprint:Y,usage:{state:"network",reason:`账号身份读取失败:${String(H)}`}}}let V=Y??Q.id,X=Z.get(V);if(!X)X=$?.id===Q.id?Promise.resolve($.usage):Jz(Q.id),Z.set(V,X);let z=await X;if(z.state==="ok"&&z.accountFingerprint)Y=z.accountFingerprint;return{account:Q,usage:z,fingerprint:Y}}));return bJ(J)}var kJ=R(()=>{j0();J$();h();E8();Q2()});import{createHash as qG,randomUUID as pU}from"node:crypto";function v4($,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 wJ($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function T$($){let Z=H$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function z$($){return!H$.has($)}function E$($,Z,J){H$.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,uncertainAdds:new Set,confirmedAdds:new Set,failedReplacements:new Set,onFailure:J,closing:!1})}function e9($){return H$.get($)?.elementCount??0}function DG($){let Z=H$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function y4($,Z){return H$.get($)?.deadElements.has(Z)??!1}function FG($,Z){let J=H$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function N7($){let Z=T$($);return Z.sequence+=1,Z.sequence}function vJ($,Z){$.deadElements.add(Z)}function UG($){return qG("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function iU($,Z,J){let Q=[...$.contentFingerprints].filter(([Y])=>Y!==Z).map(([,Y])=>Y);if(J&&Z!==C.footer)Q.push(J);return qG("sha256").update(Q.sort().join(`
121
+ `)).digest("hex")}async function r9($,Z,J,Q){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:pU()}:{}}):void 0,V=`cardkit ${$} ${Z}`;return t1(V,async()=>{let X=await m$(),z=AbortSignal.timeout(lU),H;try{return H=await X0(`${cU}${Z}`,{method:$,headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:z}),(await B$(H,V))?.data}catch(G){if(z.aborted&&z.reason?.name==="TimeoutError")G=z.reason;if(H&&G instanceof y0)Object.assign(G,{httpStatus:H.status});throw Q?.(G),G}},{api:"cardkit"})}function yJ($){return $ instanceof y0&&($.code===200770||$.code==="200770")}function MG($){if(yJ($))return!1;if($ instanceof y0){if($.status===429||$.code===99991400||$.code===230020)return!1;if($.status!==void 0&&$.status>=200&&$.status<300&&$.code===void 0)return!0}return Q8($,{api:"cardkit"})}async function R7($,Z,J,Q){let Y=!1;try{await r9(Z,J,{...Q,sequence:N7($)},(V)=>{if(MG(V))Y=!0})}catch(V){if(!Y||!yJ(V))throw V;B(`cardkit confirm ${Z} ${J}: ${V}; retrying same state with new UUID and sequence`),await r9(Z,J,{...Q,sequence:N7($)})}}async function OG($,Z,J,Q){let Y=J.element_id,V=!1;try{await r9("POST",`/cards/${$}/elements`,{type:Q.type??"append",...Q.targetElementId?{target_element_id:Q.targetElementId}:{},elements:JSON.stringify([J]),sequence:N7($)},(X)=>{if(MG(X)){if(V=!0,Y)Z.uncertainAdds.add(Y)}})}catch(X){let z=X,H=Y&&Z.uncertainAdds.has(Y)&&wJ(z?.code,z);if(!Y||!(H||V&&yJ(X)))throw X;B(`cardkit reconcile uncertain add ${$} element=${Y}: ${X}; confirming latest content with PUT`),await R7($,"PUT",`/cards/${$}/elements/${Y}`,{element:JSON.stringify(J)})}if(!Y||!Z.confirmedAdds.has(Y))Z.elementCount++;if(Y)Z.confirmedAdds.add(Y),Z.uncertainAdds.delete(Y)}function nU($){return new Promise((Z)=>setTimeout(Z,$))}function aU($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function oU($){await R7($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}})})}async function T7($,Z,J,Q,Y=!1,V={}){let X=(z)=>{let H=typeof z==="object"&&z!==null?z:null,G={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:H?.code,httpStatus:H?.httpStatus,logId:H?.logId,message:z instanceof Error?z.message:String(z),apiMessage:H?.apiMessage};if(v4(G.code,G))G.capacityFingerprint=iU(T$($),V.elementId,V.contentFingerprint);try{if(!Y||Y==="non-capacity"&&v4(G.code,G))T$($).onFailure?.(G.code,G)}catch(W){B(`cardkit failure callback ${$}: ${W}`)}try{Q?.(G)}catch(W){B(`cardkit per-call failure callback ${$}: ${W}`)}};try{await J();return}catch(z){if(!aU(z)){B(`cardkit ${Z} ${$}: ${z}`),X(z);return}B(`cardkit ${Z} ${$}: streaming closed (code=${z.code}) — reopening`)}try{await oU($)}catch(z){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${z}`),X(z);return}try{await J()}catch(z){B(`cardkit ${Z} ${$} retry-after-reopen: ${z}`),X(z)}}function sU($){return typeof $==="object"&&$!==null&&$.code===200740}async function l$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:uU,Q=null;for(let Y=0;Y<J.length;Y++){let V=J[Y]??0;if(V>0)await nU(V);try{let X=await r9("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,!sU(X)||Y===J.length-1)throw X;let z=J[Y+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${z}ms`)}}throw Q}async function v1($){let Z=H$.get($);if(!Z)return;await Z.queue}function T0($,Z,J={},Q,Y="all"){if(z$($))return Promise.resolve();let V=T$($);if(V.closing)return Promise.resolve();let X=S1(Z),z=X.element_id,H=UG(X),G=()=>{if(!z)return;vJ(V,z),V.failedAdds.set(z,J)};return V.queue=V.queue.then(()=>T7($,"addElement",async()=>{if(await OG($,V,X,J),z!==C.footer)V.contentFingerprints.set(z??`#${V.sequence}`,H);if(z)V.deadElements.delete(z),V.failedAdds.delete(z),V.failedReplacements.delete(z)},(W)=>{G(),Q?.(W.code,W)},Y==="capacity"?"non-capacity":!1,{elementId:z,targetElementId:J.targetElementId,contentFingerprint:H})),V.queue}function F0($,Z,J,Q,Y=!0){if(z$($))return Promise.resolve();let V=T$($);if(V.closing)return Promise.resolve();let X=S1(J),z=UG(X),H=()=>{vJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>T7($,`replaceElement ${Z}`,async()=>{let G=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!G&&!V.failedReplacements.has(Z))return;if(G)await OG($,V,X,G);else await R7($,"PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(X)});if(V.deadElements.delete(Z),V.failedAdds.delete(Z),V.uncertainAdds.delete(Z),V.failedReplacements.delete(Z),Z!==C.footer)V.contentFingerprints.set(Z,z)},(G)=>{if(Y)H();Q?.(G.code,G)},!Y,{elementId:Z,contentFingerprint:z})),V.queue}async function B0($,Z,J,Q={}){if(z$($))return!1;let Y=T$($);if(Y.closing)return!1;let V=!1;return await F0($,Z,J,(X,z)=>{if(V=!0,z)Q.onFailure?.(z)},Q.notifyCardFailure!==!1),!V&&!Y.deadElements.has(Z)}async function AG($,Z,J){if(z$($))return{landed:!1};let Q=T$($);if(Q.closing)return{landed:!1};let Y;return await F0($,Z,J,(V,X)=>{Y=X}),{landed:!Y&&!Q.deadElements.has(Z),...Y?{failure:Y}:{}}}async function N2($,Z,J={}){let Q=await f4($,Z,J);if(Q.failure)J.onFailure?.(Q.failure);return Q.landed}async function f4($,Z,J={}){if(z$($))return{landed:!1};let Q=T$($);if(Q.closing)return{landed:!1};let Y=Z.element_id,V;return await T0($,Z,J,(X,z)=>{V=z}),{landed:!V&&!(Y&&Q.deadElements.has(Y)),...V?{failure:V}:{}}}function tU($,Z,J){if(z$($))return Promise.resolve();let Q=T$($);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(()=>T7($,`deleteElement ${Z}`,async()=>{if(Y())return;let V=N7($);await r9("DELETE",`/cards/${$}/elements/${Z}`,{sequence:V}),Q.elementCount=Math.max(0,Q.elementCount-1),Q.contentFingerprints.delete(Z),Q.failedAdds.delete(Z),Q.uncertainAdds.delete(Z),Q.confirmedAdds.delete(Z),Q.failedReplacements.delete(Z),vJ(Q,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Q.queue}async function NG($,Z,J){if(z$($))return!1;let Q=T$($);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 tU($,Z,(V,X)=>{if(Y=!0,X)J?.(X)}),!Y&&Q.deadElements.has(Z)}function h4($,Z){if(z$($)||H$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=A2.get($);if(!Q)Q={latest:J,lastSent:"",timer:null,inFlight:!1},A2.set($,Q);else{if(Q.latest===J)return;Q.latest=J}RG($,Q)}function RG($,Z){if(Z.timer||Z.inFlight||Z.latest===Z.lastSent)return;Z.timer=setTimeout(()=>{if(A2.get($)!==Z)return;if(Z.timer=null,z$($)||H$.get($)?.closing){A2.delete($);return}if(Z.latest===Z.lastSent)return;let J=Z.latest;Z.inFlight=!0,k0($,{config:{summary:{content:J}}}).then((Q)=>{if(A2.get($)!==Z)return;if(Z.inFlight=!1,Q)Z.lastSent=J;if(Z.latest!==J&&!z$($)&&!H$.get($)?.closing)RG($,Z)})},dU)}function a0($){let Z=A2.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;A2.delete($)}function E7($,Z){return k0($,Z).then(()=>{})}async function k0($,Z,J){if(z$($))return!1;let Q=T$($);if(Q.closing)return!1;let Y=!1,V=!1;return Q.queue=Q.queue.then(()=>T7($,"patchSettings",async()=>{if(z$($))return;await R7($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z)}),Y=!0},(X)=>{V=!0,J?.(X)},!0)),await Q.queue,Y&&!V&&!z$($)}async function q$($){let Z=H$.get($);if(!Z){a0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,a0($),await Z.queue,H$.delete($)}var cU="https://open.feishu.cn/open-apis/cardkit/v1",lU=15000,uU,H$,A2,dU=1500;var G1=R(()=>{p0();$0();o2();h();h0();uU=[0,250,750,1500];H$=new Map,A2=new Map});function W1($){if(!$)return"积分 MISS";if($2($)==="empty")return null;if($.unlimited)return"积分 无限";if($.balance===null)return"积分 MISS";return`积分 ${$.balance.toLocaleString("en-US",{maximumFractionDigits:20})}`}function u$($){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 TG($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(H)=>`&#${H.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",z=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${u$($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Y)}%${Q}**
122
+ <font color='${X}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${z}</font>`,text_size:"notation"}]}var I4=()=>{};var CG={};r$(CG,{codexAccountSummary:()=>$3,codexAccountPanel:()=>Z3,codexAccountCard:()=>n$,CODEX_ACCOUNTS_PAGE_SIZE:()=>x7});function i$($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function EG($){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 $3($){let[Z,J]=SG[$.phase],Q=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Q?`${Q} · `:""}${$.title??J}`}function n$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:$3($)}},body:{elements:[Z3($)]}}}function Z3($){let[,,Z]=SG[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Q=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(U0(["连接","授权","就绪"].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(EG([[d$("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[U0(`[**打开授权页 ↗**](${Q.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),d$("登录账号,输入左侧验证码")]]))}if($.current)J.push(EG([[d$("当前使用"),U0(`**${i$($.current)}**`)],...$.selected&&$.selected!==$.current?[[d$("下次启动"),U0(`**${i$($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(U0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Q)=>i$(Q)).join(" · ")));if($.message)J.push(U0(i$($.message)));if($.resetUsage){let Q=$.resetUsage;if(J.push(U0(`**重置卡** ${Q.state==="ok"&&Q.resetCredits!=null?`${Q.resetCredits} 次可用`:"MISS"}`)),Q.state==="ok"){let Y=W1(Q.credits);if(Y)J.push(U0(Y));for(let[V,X]of[[Q.fiveHour,"5h"],[Q.weekly,"周"]])if(V)J.push(...TG(V,X))}else J.push(U0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...rU($));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:[U0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
123
+ `)),d$("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(d$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[U0(i$($.details))]});return{tag:"collapsible_panel",element_id:C.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:$3($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:$.phase==="accounts"?"8px":"12px",...$.phase==="accounts"?{vertical_spacing:"8px"}:{},elements:J}}function xG($,Z){let J=$?.percent;if(J==null||!Number.isFinite(J)||J<0||J>100)return U0(`${Z} MISS`);let Q=Math.round(J/100*6),Y=J>=100?"red":J>=80?"orange":"green",V=$.unreportedFull?"满窗":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?u$($.resetsAt):"MISS";return U0(`${Z} <font color='${Y}'>${"▰".repeat(Q)}${"▱".repeat(6-Q)}</font> ${Math.round(J)}% <font color='grey'>「${V}」</font>`)}function rU($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/x7)),Q=$.page??1;if(!Number.isInteger(Q)||Q<1||Q>J)throw Error(`页码应为 1–${J}`);let Y=[],V=$.scheduling?.candidates.filter((H)=>H.state==="ready").sort(M8)??[],X=new Map(V.map((H,G)=>[H.account.id,G+1])),z=Z.entries.slice().sort((H,G)=>(X.get(H.account.id)??1/0)-(X.get(G.account.id)??1/0));for(let H of z.slice((Q-1)*x7,Q*x7)){let G=H.usage,W=[],K=$.scheduling?.candidates.find((L)=>L.account.id===H.account.id),j=X.get(H.account.id),_=H.duplicateOf?"重复":K?.state==="ready"?K.funding==="credits"?"积分":K.priority==="expiring"?"临期优先":`${K.score.toPrecision(3)}/h`:"MISS";if(Y.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`#${j??"—"}·${H.account.name}「${_}」 · 重置 ${G.state==="ok"?G.resetCredits??"MISS":"MISS"}`},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"2px",elements:W}),W.push(d$(`邮箱:${H.email??"MISS"}`)),H.emailError)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"邮箱查询错误"}},elements:[U0(i$(H.emailError))]});if(H.duplicateOf){W.push(d$(`与「${H.duplicateOf}」同一账号,合计只计一次`));continue}if(K&&K.state!=="ready"){if(W.push(d$(K.state==="exhausted"?"⏳ 暂不可用":K.state==="excluded"?"Ultra 自动排除 Plus":K.state==="waiting"?`⏳ 周余量 ${K.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),K.reason&&G.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[U0(i$(K.reason))]})}if(G.state!=="ok"){if(W.push(U0(G.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),G.state==="network"&&G.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[U0(i$(G.reason))]});continue}if(W.push(xG(G.weekly,"周")),G.fiveHour)W.push(xG(G.fiveHour,"5h"));let D=W1(G.credits);if(D)W.push(U0(D));let P=$.activationErrors?.[H.account.id];if(P)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"后台激活 MISS"}},elements:[U0(i$(P))]})}if(J>1)Y.push(d$(`${Q}/${J} 页 · ${Q<J?`下一页 codex-accounts ${Q+1}`:"首页 codex-accounts"}`));return Y}var x7=4,SG,U0=($)=>({tag:"markdown",content:$}),d$=($)=>({tag:"markdown",content:`<font color='grey'>${i$($)}</font>`,text_size:"notation"});var g4=R(()=>{h0();I4();Q2();SG={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"]}});class m4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=eU){let Q,Y=await J.sendCard($,n$(Z,!0),(X)=>{Q=X});if(!Y)throw Error(`Codex 账号卡片发送失败:${w(Q)}`);let V=await J.convertMessageToCard(Y);return J.recordCardCreated(V,1),new m4(V,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=Z3($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=Z3($);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,Y,V=await this.deps.replaceElementChecked(this.cardId,C.codexAccountPanel,Z,{notifyCardFailure:!1,onFailure:(z)=>{Q=z}}),X=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:$3($)}}},(z)=>{Y=z});if(!V||!X)throw Error(`Codex 账号卡片更新失败:内容 ${V?"OK":w(Q)},状态 ${X?"OK":w(Y)}`);if(J)await this.deps.dispose(this.cardId)}}var eU;var bG=R(()=>{$0();G1();h0();g4();eU={sendCard:n,convertMessageToCard:l$,recordCardCreated:E$,replaceElementChecked:B0,patchSettingsChecked:k0,dispose:q$}});var hJ={};r$(hJ,{settleCodexAccountCards:()=>fJ,runCodexNamedHi:()=>ZM,runCodexAccountCommand:()=>JM});import{createHash as $M}from"node:crypto";function J3($,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 kG($,Z){let J;if(!await n($.chatId,n$(J3(Z)),(Q)=>{J=Q}))throw Error(`Codex 错误卡片发送失败
124
+ ${w(J)}`)}async function ZM($,Z){let J=await m4.open($.chatId,{phase:"checking",name:Z,message:"正在启动指定账号…"});try{let Q=v.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(J3(Q,Z))}}async function fJ(){let Z=(await Promise.allSettled([...T2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function JM($,Z,J,Q,Y){if(Z==="reset"){await YM($,J,Y);return}let V={chatId:$.chatId,userOpenId:Q};if(Z==="login-cancel"){try{let G=D2.pending(V);if(!J&&G.length!==1)throw Error(G.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?v.find(J).id:G[0];await D2.cancel(W,V),await T2.get(W)}catch(G){await kG($,G)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,z=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),H=await m4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号邮箱与额度…":z?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let _=v.find(J);if(T2.has(_.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:D}=v.remove(_.id);mz(C0("codex-sub"),_.id),f$(_.id),await H.finish({phase:"deleted",name:_.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:D?`已清除 ${D} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let _=J?Number(J):1,D=$.codexAccountId(),P=G0("codex-sub",D),L=()=>$.currentProvider()==="codex"?$.currentModelLabel():P?.defaultModel,F=L(),U;if(!F)try{if(!P)throw Error("Codex 订阅来源尚未初始化");if(F=L(),!F)throw Error(P.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(T){U=`${v.get(D).name}:${T instanceof Error?T.message:String(T)}`}let A=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,M=F?await W2.choose({model:F,effort:A}):null,O=M?bJ(M.candidates.flatMap((T)=>{let E=(T.usage?.state==="network"||T.usage?.state==="rate_limited"?H2(T.account.id):null)??T.usage;return E?[{account:T.account,usage:E,fingerprint:T.identity.startsWith("record:")?null:T.identity}]:[]})):await A7();if(U)B(`codex-accounts: scheduling MISS: ${U}`);await H.finish({phase:"accounts",total:await PG(O),currentId:D,activationErrors:Object.fromEntries(O.entries.flatMap((T)=>{let k=T9.error(T.account.id);return k?[[T.account.id,k]]:[]})),...v.preferred($.sessionName)?{selectedId:v.selected($.sessionName)}:{},page:_,...M?{scheduling:{candidates:M.candidates,ultra:A==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:U,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");v.selectAuto($.sessionName),await H.finish({phase:"selected",name:"自动选择",current:v.get($.codexAccountId()).name,selected:"自动 · 临期 / 评分",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await H.finish({phase:"current",current:v.get($.codexAccountId()).name,selected:v.preferred($.sessionName)===null?"自动 · 临期 / 评分":v.get(v.selected($.sessionName)).name,hint:"周剩余份额 ÷(重置小时 − 5)· codex-auto"});return}let _=v.find(J),D=$.currentProvider()==="codex"?$.currentModelLabel():null,P=$.currentProvider()==="codex"?$.currentEffortLabel():null,L=v.get($.codexAccountId()).name;if($.currentProvider()==="codex")w1($.sessionName,"codex",D,P,"codex-sub");if(v.select($.sessionName,_.id),$.currentProvider()==="codex")$.selectedModel=D,$.selectedEffort=P,$.selectedTokenSourceId="codex-sub";await H.finish({phase:"selected",name:_.name,current:L,selected:_.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Q)throw Error("无法确认登录发起者");if(z)await xH(),await H.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let G=v.ensure(J);if(L8(G.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(T2.has(G.id))throw Error("登录结果正在更新,请稍等");let W=await D2.start(G.id,V);try{await H.update({phase:"waiting",flow:"login",name:G.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${G.name}`:""}`})}catch(_){throw await D2.cancel(G.id,V),_}let K=(async()=>{let _;try{_=await W.done}catch(D){await H.finish(J3(D,G.name));return}t9(),G0("codex-sub",G.id),await H.finish({phase:"success",flow:"login",name:G.name,email:_.email,plan:_.planType,hint:`目录与额度正在后台刷新 · 优先使用:codex-account ${G.id==="default"?"default":G.name}`})})();T2.set(G.id,K);let j=()=>{if(T2.get(G.id)===K)T2.delete(G.id)};K.then(j,(_)=>{B(`codex-login: terminal card write failed: ${_}`),j()})}catch(G){B(`codex-${Z}: ${G}`),await H.finish(J3(G,X))}}async function YM($,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?v.find(Z):v.get(j$($.proc))}catch(G){B(`codex-reset: ${G}`),await kG($,G);return}let Y=await m4.open($.chatId,{phase:"checking",name:Q.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let G=$M("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await rX(Q.id,G)}catch(G){B(`codex-reset: ${G}`),await Y.finish(J3(G,Q.name));return}let X=QM[V.outcome],H=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
125
+ `);await Y.finish({...X,name:Q.name,resetUsage:V.usage,...H?{phase:"warning",details:H}:{},hint:"codex-accounts 查看各账号额度"})}var T2,QM;var S7=R(()=>{$0();j0();WJ();z0();O7();u8();kJ();w8();YZ();bG();g4();h();J$();T2=new Map;QM={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as VM}from"node:fs";function XM($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function zM($,Z){let J=[`[token_source.${$}]`],Q=(Y,V)=>{if(V!==void 0)J.push(`${Y} = "${XM(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(`
126
+ `)}function HM($,Z){GM({[$]:Z})}function GM($){if(!Object.keys($).length)return;let Z=VM(v0,"utf8"),J=_9().token_sources,Q={};for(let[H,G]of Object.entries($)){let W=PJ(J,H,G);J={...J,...W},Object.assign(Q,W)}n9(J);let Y=new Set(Object.keys(Q).map((H)=>`[token_source.${H}]`)),V=Z.split(`
126
127
  `),X=!1,z=[];for(let H of V){let G=H.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(G)X=Y.has(G);if(!X)z.push(H)}while(z.length&&z[z.length-1]==="")z.pop();r0(v0,z.join(`
127
128
  `)+`
128
129
 
129
- `+Object.entries(Q).map(([H,G])=>nU(H,G)).join(`
130
+ `+Object.entries(Q).map(([H,G])=>zM(H,G)).join(`
130
131
 
131
132
  `)+`
132
- `)}function J3($){let Z=TG.then($);return TG=Z.then(()=>{},()=>{}),Z}async function Q3($,Z,J){aU($,Z),J?.(),LX(),s9()}function EG($,Z){return J3(()=>Q3($,Z))}async function xG($,Z,J=$.setup){let Q=!1;try{if(!$.configSectionId||!J)throw Error("此来源不支持配置命令");let Y=$.configSectionId,V=()=>{let z=j9().token_sources;return i9({...z,...PJ(z,Y,Z)})[Y]},X=V();await J.validate(X),await J3(async()=>{if(JSON.stringify(V())!==JSON.stringify(X))throw Error("校验期间账号配置已变化,本次未保存,请重试");await Q3(Y,Z,()=>{Q=!0})})}catch(Y){throw new S7(Y,Q)}}function SG($,Z,J,Q="default"){return J3(async()=>{let Y=G0($,Q);if(!Y?.enabled||!Y.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Y.modelSelection.modelIds.filter((j)=>Y.models.find((_)=>_.model===j)?.origin!=="custom");if(J==="add"){if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");let j=Y.modelSelection.availableModels.find((_)=>_.model===Z);if(j?.origin==="custom")throw Error("补录模型请使用删除操作");if(!j||Y.modelSelection.mode!=="catalog"&&(j.unavailableReason||!j.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((j)=>j!==Z),z=m.token_sources[$],H=Y.modelSelection.mode==="catalog",G=r(z?.hidden_models),W=H?{hidden_models:(J==="remove"?[...new Set([...G,Z])]:G.filter((j)=>j!==Z)).join(",")}:{models:X.join(",")};await Q3($,W);let K=G0($,Q);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function CG($,Z,J="default"){return J3(async()=>{let Q=Z.trim();if(!Q||Q.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Q))throw Error("模型 ID 无效,请只填写一个完整模型名");let Y=G0($,J);if(!Y?.enabled)throw Error("账号不可用");if(Y.validateCustomModelId?.(Q),(Y.modelSelection?.availableModels??Y.models).some((H)=>H.model.toLowerCase()===Q.toLowerCase()))throw Error("模型已在目录或补录记录中;隐藏项请使用“显示”");if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");let X=m.token_sources[$];await Q3($,{custom_models:[...r(X?.custom_models),Q].join(",")});let z=G0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}function bG($,Z,J="default"){return J3(async()=>{let Q=G0($,J),Y=Q?.modelSelection?.availableModels.find((G)=>G.model===Z);if(!Q?.enabled||Y?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=m.token_sources[$]??{},X=(G)=>G?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),z={custom_models:r(V.custom_models).filter((G)=>!X(G)).join(","),hidden_models:r(V.hidden_models).filter((G)=>!X(G)).join(","),...V.models!==void 0?{models:r(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 Q3($,z);let H=G0($,J);if(H?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${H?.modelCatalogState?.error??"MISS"}`)})}var TG,S7;var hJ=N(()=>{H0();f0();M7();X0();x0();V1();n9();TG=Promise.resolve();S7=class S7 extends Error{saved;constructor($,Z){super($ instanceof Error?$.message:String($),{cause:$});this.saved=Z}}});var C7={};r$(C7,{runTokenSourceSetup:()=>rU,runClaudeSubscriptionCommand:()=>sU,onTokenSourceEnable:()=>tU});async function sU($,Z){if(Z&&Z!=="on"&&Z!=="off"){await k($.chatId,`用法:${"claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"}`);return}if(Z)try{await EG("claude-sub",{enabled:Z==="on"})}catch(z){let H=z instanceof Error?z.message:String(z);B(`claude-sub ${Z} failed: ${H}`),await k($.chatId,`❌ Claude Code 订阅开关更新失败:${H}`);return}let Q=C0("claude-sub"),Y=m.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"?"模型目录缓存尚未就绪,后台刷新中":"订阅来源不可用")}`);if(X.push("所有群共用;保留本机登录态。"),!Y)X.push("禁止新任务,已在执行的任务继续完成。");X.push("claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"),await k($.chatId,X.join(`
133
- `))}async function tU($,Z){let J=C0(Z);if(!J){await k($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled&&J.modelCatalogState?.status!=="failed"){await k($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Q=H2().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup){let Y=J.modelCatalogState?.status==="failed"?`${J.display} 当前不可用:${c0(J.modelCatalogState.error??"MISS")}
134
- `:"";await k($.chatId,Y+Q.setup.hint(J.display))}else if(J.kind==="codex-subscription"){if(!await i($.chatId,n$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await k($.chatId,m.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 k($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function rU($,Z,J){let Q=H2().find((H)=>H.setup?.commandSuffix===Z||H.usageSetup?.commandSuffix===Z),Y=Q?.usageSetup?.commandSuffix===Z,V=Y?Q?.usageSetup:Q?.setup;if(!Q||!V||!Q.configSectionId){await k($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let X=V.parseArgs(J);if("error"in X){await k($.chatId,X.error);return}await k($.chatId,"正在后台校验账号配置,完成后会返回结果;其他操作可继续使用。");let z=!1;try{await xG(Q,X.config,V),z=!0;let H=C0(Q.configSectionId),G=SH(Q.configSectionId).map((j)=>C0(j)),W=G.find((j)=>(!Y||j?.enabled)&&j?.modelCatalogState?.status!=="ready");if(Y){let j=W?`
135
- 模型目录仍为 MISS:${c0(W.modelCatalogState?.error??"尚未就绪",[X.config.management_token])}`:"";await k($.chatId,`✅ ${H?.display??Z} 真实余额校验通过,配置已保存。发送 hi 查看;回复页脚使用同一账户余额。${j}`);return}if(W?.modelCatalogState?.status==="failed"||G.some((j)=>!j)){let j=c0(W?.modelCatalogState?.error??"模型目录尚未就绪",[X.config.api_key,X.config.auth_token]);await k($.chatId,`❌ ${H?.display??Z} 凭据校验通过、配置已保存,但暂不可用:${j}
136
- 处理后等待后台刷新,发送 md 查看状态。`);return}let K=[...new Set(G.filter((j)=>!!j).map((j)=>i0(j.agent)))];await k($.chatId,`✅ ${H.display} 校验通过,配置已保存。${K.length>1?`${K.join(" 和 ")} 共用该账号。`:""}目录与额度在后台刷新;发送 md 查看模型。`)}catch(H){let G=z||H instanceof S7&&H.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",W=c0(H,[X.config.api_key,X.config.auth_token,X.config.management_token]);await k($.chatId,`❌ ${G}:${W}`)}}var b7=N(()=>{$0();X0();hJ();g4();f0();h();n9();_0()});function kG($,Z){let J=Z.catch(async(Q)=>{let Y=`账号操作或结果呈现失败:${S(Q)}`;throw B(Y),await I($.chatId,`❌ ${Y}`),Q});IJ.add(J),J.finally(()=>IJ.delete(J)).catch((Q)=>B(`账号操作结果发送失败:${S(Q)}`))}function wG(){return[...IJ]}async function vG($,Z,J="",Q){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (x7(),fJ));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(() => (x7(),fJ)),j=V[1].toLowerCase(),_=K($,j,(V[2]??"").trim(),J,Q);if(j==="login"||j==="reset")kG($,_);else await _;return!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (b7(),C7));return await K($,(X[1]??"").trim().toLowerCase()),!0}let z=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(z)return await $.runWorktreeCommand((z[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 H=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(H)return await $.runFileDeliveryCommand((H[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(() => (b7(),C7));return kG($,K($,G[1].trim().toLowerCase(),(G[2]??"").trim())),!0}let W=eU.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(),j=$.backendLabel(),_=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${j}`)):null,D=$.withModel(`\uD83D\uDE80 启动 ${j}`);if(!(K?await $.start({announce:!_,onStatus:(P)=>{D=P,$.setStatusCard(_,P)}}):!0))return await $.closeStatusCard(_,D.startsWith("❌")?D:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(_)await $.closeStatusCard(_,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:F}=await Promise.resolve().then(() => (g4(),AG)),U;if(!await i($.chatId,F({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"}),(A)=>{U=A}))throw Error(`额度等待卡片发送失败
137
- ${v(U)}`)}return!0}if(_)return await $.replaceStatusCardWithConsole(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let _=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!_,onStatus:(D)=>$.setStatusCard(_,D)}),await $.closeStatusCard(_,"\uD83D\uDED1 已取消额度恢复")}catch(D){throw await $.closeStatusCard(_,`❌ ${S(D)}`),D}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(K)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await k($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let _=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(_)await $.closeStatusCard(_,"⚪ 无正在执行的 turn");else await k($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let j=new Set;for(let[_,D]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(D)g0(_,D);X$(_,"CrossMark"),j.add(_)}for(let _ of $.pendingMidTurnMsgs)if(_.msgId&&!j.has(_.msgId))X$(_.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0}case"kill":{let K=$.isRunning(),j=$.backendLabel($.proc?.provider??$.currentProvider()),_=K?`\uD83D\uDED1 停止 ${j}`:"⚪ session 当前未运行",D=await $.openStatusCard("kill",_,K?"red":"grey"),L=null,P=K?`✅ ${j} 已终止`:`⚪ ${j} 未运行`;try{await $.stop("已终止",{announce:!D,onStatus:(F)=>{$.setStatusCard(D,F)}})}catch(F){L=F,P=$.isRunning()?`❌ ${j} 未确认终止: ${S(F)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${j} 停止收尾失败: ${S(F)}`}finally{try{await $.closeStatusCard(D,P)}catch(F){B(`session "${$.sessionName}": kill status card close failed: ${S(F)}`),await I($.chatId,`${P}
138
- ⚠️ kill 状态卡片终态写入失败: ${S(F)}`)}}if(L&&!D)await I($.chatId,P)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?S0($.lastSessionId):"",j=$.backendLabel($.proc?.provider??$.currentProvider()),_=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${j}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${j}`),D=await $.openStatusCard("restart",_),L=_,P=await $.restart(!0,{announce:!D,onStatus:(U)=>{L=U,$.setStatusCard(D,U)}}),F=P?L.startsWith("✅")?L:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):L.startsWith("❌")?L:"❌ 重启失败";await $.closeStatusCard(D,P?$.withModel(F):F)}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 k($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let K=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),j="\uD83E\uDDF9 清空并启动新会话",_=await $.restart(!1,{announce:!K,onStatus:(D)=>{j=D,$.setStatusCard(K,D)}});await $.closeStatusCard(K,_?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):j.startsWith("❌")?j:"❌ 清空失败")}return!0}}var eU,IJ;var gJ=N(()=>{$0();h();eU=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"]]),IJ=new Set});function E0($,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 T2($){switch($){case"project":return"项目任务";case"delegated":return"委派任务";case"subagent":return"子 Agent";case"background":return"后台进程"}}function fG($){switch($){case"project":return"\uD83D\uDCC2";case"delegated":return"\uD83E\uDDE0";case"subagent":return"\uD83E\uDD16";case"background":return"⚙️"}}var yG;var mJ=N(()=>{yG=["delegated","project","subagent","background"]});function Y3($,Z=360){let J=$.replace(/\s+/g," ").trim();if(!J)return"说明 MISS";if(J.length<=Z)return J;let Q="_任务内容已精简,完整内容仅用于执行。_",Y=Math.max(1,Z-Q.length-2);return`${J.slice(0,Y)}…
139
-
140
- ${Q}`}function k7($,Z=8000){if($.length<=Z)return $;let J="_结果超过卡片安全上限,已截断。_",Q=Math.max(1,Z-J.length-2);return`${$.slice(0,Q)}…
141
-
142
- ${J}`}function hG($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function ZM($,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 IG($){return $==="workflow"||$==="monitor"}function D$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function cJ($){return $.some((Z)=>!D$(Z))}function X3($,Z,J=Date.now()){let Q=ZM(Z.task_type,Z.subagent_type),Y=(H)=>H.id===Z.task_id||!!Z.tool_use_id&&H.toolUseId===Z.tool_use_id,V=$.active.some(Y),X=$.pending.some(Y);if(V||X){let H=(G)=>({...G,...D$(G)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type:Q==="unknown"?G.type:Q,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&&Q==="subagent")return{active:[...$.active,...$.pending.filter(Y).map(H)],pending:$.pending.filter((G)=>!Y(G))};return{active:V?$.active.map((G)=>Y(G)?H(G):G):$.active,pending:X?$.pending.map((G)=>Y(G)?H(G):G):$.pending}}let z={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:[],...IG(Q)?{isBackgrounded:!0}:{}};return Q==="subagent"||IG(Q)?{active:[...$.active,z],pending:$.pending}:{active:$.active,pending:[...$.pending,z]}}function lJ($,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 uJ($,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],z={...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,z],pending:$.pending.filter((H)=>H.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Y||V){let X=(z)=>({...z,status:Q.status??z.status,description:Q.description??z.description,error:Q.error??z.error,isBackgrounded:Q.is_backgrounded??z.isBackgrounded,endTime:Q.end_time??z.endTime});return{active:Y?$.active.map((z)=>z.id===Z.task_id?X(z):z):$.active,pending:V?$.pending.map((z)=>z.id===Z.task_id?X(z):z):$.pending}}return $}function dJ($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function v7($,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 w7($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>JM){J=Q+1;break}return J===0?$:$.slice(J)}function QM($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return Y4(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 YM($,Z){let Q=((typeof $==="string"?$:Array.isArray($)?$.map((Y)=>typeof Y?.text==="string"?Y.text:JSON.stringify(Y)).join(`
143
- `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Q.slice(0,80)}`:Q.slice(0,80)}function iJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((H)=>H.toolUseId===Z),X=$.pending.some((H)=>H.toolUseId===Z);if(!V&&!X)return $;let z=(H)=>H.map((G)=>G.toolUseId===Z?{...G,steps:w7([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${QM(Q,Y)}`.trim()}])}:G);return{active:V?z($.active):$.active,pending:X?z($.pending):$.pending}}function nJ($,Z,J,Q,Y,V){let X=$.active.some((G)=>G.id===Z),z=$.pending.some((G)=>G.id===Z);if(!X&&!z)return $;let H=(G)=>G.map((W)=>{if(W.id!==Z)return W;if(Y==="started")return{...W,steps:w7([...W.steps,{toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()}])};let K=!1,j=W.steps.map((_)=>{if(K||_.toolUseId!==J)return _;return K=!0,{..._,brief:V?`${_.brief} ${V}`:_.brief}});if(!K&&V)j.push({toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()});return{...W,steps:w7(j)}});return{active:X?H($.active):$.active,pending:z?H($.pending):$.pending}}function aJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((H)=>H.toolUseId===Z),X=$.pending.some((H)=>H.toolUseId===Z);if(!V&&!X)return $;let z=(H)=>H.map((G)=>{if(G.toolUseId!==Z)return G;let W=!1,K=G.steps.map((j)=>{if(W||j.toolUseId!==J)return j;return W=!0,{...j,brief:`${j.brief} → ${YM(Q,Y)}`}});return{...G,steps:w7(K)}});return{active:V?z($.active):$.active,pending:X?z($.pending):$.pending}}function z3($){return $.type==="subagent"?"subagent":"background"}function lG($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of VM)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:`${E0((Q+1)*600,"down")}+`,nextDelayMs:Y-Z}}function p4($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=pJ){let Q=Math.floor((J-pJ)/gG),Y=pJ+(Q+1)*gG;return{label:`${E0((10+Q*5)*60,"down")}+`,nextDelayMs:Y-J}}return{label:E0(Math.floor(J/1000)),nextDelayMs:cG}}return lG($)}function mG($){return $.subagentType??$.workflowName??pG[$.type]}function XM($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function zM($){let Z=T2(z3($)),J=pG[$.type],Q=[`**${Z}${J!==Z?` · ${J}`:""}**${mG($)!==J?` · ${mG($)}`:""}${D$($)?` · 用时 ${E0(XM($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Q.push(`⚠ ${$.error}`);if($.summary)Q.push("",`**${D$($)?"结果":"进度"}**`,D$($)?k7($.summary):Y3($.summary));if($.prompt)Q.push("","**任务说明**",Y3($.prompt));if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3))Q.push(`- ${Y.brief}`)}else if($.lastToolName)Q.push("",`最近动作:${$.lastToolName}`);return J0(Q.join(`
144
- `))}function y7($){let Z=T2(z3($)),J={running:`⏳ ${Z}正在执行`,pending:`⏳ ${Z}等待执行`,paused:`⏸️ ${Z}已暂停`,completed:`✅ ${Z}完成`,failed:`❌ ${Z}失败`,killed:`\uD83D\uDED1 ${Z}已终止`}[$.status],Q=$.description.replace(/\s+/g," ").trim()||"说明 MISS";return`${J} · ${Q.length<=40?Q:`${Q.slice(0,39)}…`}`}function oJ($){return{tag:"collapsible_panel",element_id:V3.panel($.id),header:{title:{tag:"plain_text",content:y7($)}},expanded:!1,elements:[{tag:"markdown",element_id:V3.body($.id),content:zM($)}]}}var V3,JM=1000,pG,VM,cG=1000,pJ=600000,gG=300000;var sJ=N(()=>{h0();D8();mJ();V3={panel:($)=>`bg_${hG($)}`,body:($)=>`bgb_${hG($)}`};pG={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"};VM=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as HM}from"node:events";import{join as GM,isAbsolute as WM,extname as KM,basename as BM}from"node:path";import{readFile as jM}from"node:fs/promises";function _M($){if($.length>=8&&$.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return"image/png";if($.length>=3&&$[0]===255&&$[1]===216&&$[2]===255)return"image/jpeg";let Z=$.subarray(0,12).toString("ascii");if(Z.startsWith("GIF87a")||Z.startsWith("GIF89a"))return"image/gif";if($.length>=12&&Z.startsWith("RIFF")&&Z.slice(8,12)==="WEBP")return"image/webp";throw Error("DSH image input has unsupported or invalid raster bytes")}var f7=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),tJ,rJ;var uG=N(()=>{_0();r1();o9();h();tJ={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};rJ=class rJ extends HM{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=f7();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"};M0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new F7({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:GM($.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(tJ).find((Q)=>tJ[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)=>!WM(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(`
145
- `)}],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(KM(V).toLowerCase()))continue;let X=await jM(V);J.push({type:"image",mediaType:_M(X),name:BM(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((z)=>{let H=V?.[z.question]??V?.[z.id];if(typeof H!=="string")throw Error(`missing answer to DSH question: ${z.question}`);let G=z.options?.find((W)=>W.label===H);return{id:z.id,selected:G?[H]:[],...G?{}:{custom:H}}}):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((z)=>this.fail(z))}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(!O0(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 W2}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={...f7(),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}
146
-
147
- ${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=f7(),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=tJ[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={...f7(),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})}}});import{EventEmitter as PM}from"node:events";function DM($,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 LM="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",qM,eJ=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),$Q;var dG=N(()=>{j0();k8();J$();h();qM=["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"];$Q=class $Q extends PM{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??eJ()}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??G2}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((X)=>`${X.account.name}:${X.reason??X.state}`).join(";");if(Q.retryAt===void 0){let z=Q.candidates.some((H)=>H.state==="miss"&&!H.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()));B(`codex account: waiting for quota: ${Y}`),this.notice("暂无可用账号 · 自动等待恢复",V),this.resolveQuotaWait(),await(this.opts.wait??DM)(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,O1(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((H)=>H.usage!==null&&H.state==="miss"&&!H.duplicateOf).map((H)=>`${H.account.name}:${H.reason}`)}),this.lifetime.signal.throwIfAborted(),V.sendInitialize();let z=V.initializationPromise?.();if(!z)throw Error("Codex 初始化未提供确认事务");if(await z,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($){let Z=null;for(let J of qM)$.on(J,(...Q)=>{if(this.inner===$&&!this.closed){if(J==="token_usage"&&Z&&Q[0]?.turnId===Z&&Q[0]?.threadId===$.sessionId&&Q[0]?.usage&&Object.values(Q[0].usage).some((Y)=>typeof Y==="number"&&Number.isFinite(Y)&&Y>0)&&this.selected)this.scheduler().recordUsage(this.selected.account.id,this.lastModel||this.opts.model);if(J==="bg_task_started")this.backgroundTasks.add(Q[0].task_id);if(J==="bg_task_settled")this.backgroundTasks.delete(Q[0].task_id);this.emit(J,...Q)}});$.on("turn_retry",(J)=>{if(this.inner===$&&!this.closed)this.emit("turn_retry",J)}),$.on("turn_started",(J)=>{if(this.inner!==$||this.closed)return;Z=J.turn_id,this.result=null,this.ownRetry=null;let Q=this.retryTurn||J.retry;this.retryTurn=!1,this.emit("turn_started",{...J,...Q?{retry:!0}:{}})}),$.on("result",(J)=>{if(this.inner!==$||this.closed||this.lifetime.signal.aborted)return;if(Z=null,J?.is_error&&J.codexQuotaFailure&&!this.recovery){this.retryCount++;let Q=Promise.resolve().then(()=>this.recover($,J.codexQuotaFailure)).catch((Y)=>{if(!this.lifetime.signal.aborted)this.fail(Y)}).finally(()=>{if(this.recovery===Q)this.recovery=null});this.recovery=Q,this.notice(`「${this.selected?.account.name??"MISS"}」额度耗尽 · 正在换号续跑`);return}if(this.recovery)return;this.retryCount=0,this.result=null,this.emit("result",J)}),$.on("exit",(J)=>{if(this.inner!==$||this.closed)return;if((this.recovery||this.shutdown)&&J.expected)return;this.lifetime.abort(Error("Codex 进程退出")),this.closed=!0,this.emit("exit",J)})}async recover($,Z){if(this.lifetime.signal.throwIfAborted(),!this.selected)throw Error("额度耗尽时未记录运行账号");let J=X2(this.selected.account.id);if(J?.state==="ok")this.selected={...this.selected,usage:J,identity:J.accountFingerprint??this.selected.identity};let Q=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 V=$.isConversationResumable?.()===!0&&$.sessionId;if(Z.accepted&&!V)throw Error("额度耗尽后未确认原会话落盘,不能重放已执行的任务");if(!Z.accepted&&typeof Z.rejectedInput!=="string")throw Error("额度耗尽的拒绝响应缺少原始输入");let X=V?{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(X,void 0,Q),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let z=Z.accepted?LM:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(z),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...eJ(),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={...eJ(),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 H3($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new $Q({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,j,_,D,L)=>H3({...$,model:D,effort:L,codexAccountPreference:void 0,codexManualAccount:_,codexAccountId:K,launch:j})}),sourceRevision:null}}let Z=$.codexAccountId??c,J=G0($.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=G4(J,Y),X=!Q&&J&&I$(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 z=!Q&&J&&Y?J.resolveSpawnModel(Y):Y;if(Y&&!z)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Y}`);let H=J?(W)=>J.spawnEnv(W,z):void 0;if($.provider==="dsh"){if(!J||!z||!O0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new rJ({...$,model:z,effort:$.effort,tokenSourceId:J.id,transformEnv:H}),sourceRevision:V}}if($.provider==="claude"){if(KZ(),!R0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new g8({workDir:$.workDir,model:z,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:H,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!_$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let G=new z4({workDir:$.workDir,model:z,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:H,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z,...J?.codexApiProvider?{apiProvider:J.codexApiProvider}:{}});if(!J?.codexApiProvider)O1(G,Z);return{process:G,sourceRevision:V}}var ZQ=N(()=>{_0();uG();_4();J1();X0();j0();dG()});function c4($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function iG($){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 E2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function JQ($){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 UM($){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 MM($){let Z=E2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${JQ($.file.url)})`:Z,Q=$.status==="failed"?`<font color='red'>${E2($.error??"交付失败")}</font>`:`<font color='grey'>${iG($.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:UM($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
148
- ${Q}`}]}]}}function QQ($){let Z=$.files.filter((H)=>H.status==="ready").length,J=$.files.filter((H)=>H.status==="failed").length,Q=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Y=$.folderAccessReady&&$.folder?JQ($.folder.url):void 0,V=[...$.files.filter((H)=>H.status==="failed"),...$.files.filter((H)=>H.status!=="failed")],X=V.slice(0,FM),z=V.slice(X.length).filter((H)=>H.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:b.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(MM),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${z?`中有 ${z} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${E2($.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 YQ($){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}**
149
- 工作目录:${E2($.workDir)}
150
- 群:${E2($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:E2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${E2($.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:JQ($.settings.folder.url)}]}]:[]]}}}var FM=12;var h7=N(()=>{h0()});function I7($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function g7($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function OM($,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 aG($,Z,J){let Q=OM($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function nG($){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 m7($,Z){let J=nG($);return Z!=null&&Z>0?`${J}/${nG(Z)}`:`${J}/--`}function oG($,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 XQ($,Z,J){let Q=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Q||"MISS"}/${J||"MISS"}`}function c7($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function AM($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function NM($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function p7($){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 sG($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function rG($){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 RM($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${rG($)}`}function VQ($){return typeof $==="number"&&Number.isFinite($)?$:null}function TM($){let Z=VQ($.startedAtMs),J=VQ($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${E0((J-Z)/1000)}`}function EM($){let Z=VQ($);return Z==null?null:p7(Z)}function xM($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=EM($.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 zQ($,Z,J){if($==null||!Number.isFinite($))return null;let Q=aG($,Z,J);return Q?`${Q.used}% · ${m7($,Z)}`:"--"}function HQ($){let Z=p7($?.input_tokens??Number.NaN),J=p7($?.cache_read_input_tokens??Number.NaN),Q=p7($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function G3($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",V=Y?"✅":"⏳",X=Y?TM(Q):"",z=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,H=xM(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:z}},expanded:!1,elements:[{tag:"markdown",content:H.join(`
151
- `)}]}}function eG($,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(`- ${AM(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(`
152
- `)}function GQ($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:RM($,J)}},expanded:!1,elements:[{tag:"markdown",content:eG($,Z,J)}]}}function W3($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${rG($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:eG($,Z)}]}}function WQ($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${sG($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${E0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${sG($.status)}: ${NM($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
153
- `)}]}}function l7($){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:b.userInput,header:{title:{tag:"plain_text",content:Y}},expanded:!1,elements:Q.map((X)=>({tag:"markdown",content:J0(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:b.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function $W($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function SM($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function CM($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let V=$.options[Y],X=V.description?` · ${J0(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:`**${J0(V.label)}**${X}`}]})}return Q}function tG($,Z,J,Q){if($.length===0)return null;let Y=$.length,V=[];for(let X=0;X<$.length;X++){let z=$[X];if(!z)continue;let H=$W(z,X,Y),G=Q.get(X);if(G){let W=SM(z,G),K=[`**✅ ${H}**`,`**回答**:${W}`];V.push({tag:"markdown",content:K.join(`
154
- `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${H}**`}),z.options.length>0)V.push(...CM(z,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${H}**`})}return V}function l4($,Z,J,Q="\uD83E\uDD14",Y){let V=J.length,X=Y?.answered??new Map,z=Y?.currentIdx,H=z===void 0&&X.size>0,G=[],W;if(Y?.waitingFor)W=Y.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",G.push({tag:"markdown",content:Y.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(H){W=`${Q} 已回答 · ${V}/${V}`,G.push(...tG(J,Z,z,X)??[]);let K=[...X.values()].reverse().find((j)=>j.user)?.user;if(K)G.push({tag:"markdown",content:`
155
- *— 由 ${K} 回答*`})}else if(z!==void 0&&J[z])W=`${Q} 等你确认 · ${z+1}/${V}`,G.push(...tG(J,Z,z,X)??[]);else if(W=`${Q} 等你确认`,J[0])G.push({tag:"markdown",content:`**${$W(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!H&&!Y?.waitingFor,elements:G}}var ZW=N(()=>{h0()});import{isAbsolute as KQ,relative as bM}from"node:path";function d7($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function i7($){return $==="write_stdin"||$.endsWith(".write_stdin")}function wM($){return d7($)||i7($)}function n7($){return $==="FileChange"||$==="fileChange"}function B3($){return $==="WebSearch"||$==="webSearch"}function a7($){return $==="WebFetch"||$==="webFetch"}function qQ($){return $==="MCP"}function j3($){return $==="ImageGeneration"||$==="imageGeneration"}function DQ($){return $==="Agent"||$==="Task"}function o7($){return $==="Read"}function s7($){return $==="Write"}function t7($){return $==="Edit"||$==="NotebookEdit"}function r7($){return $==="MultiEdit"}function FQ($){return $==="Glob"||$==="Grep"||$==="LS"}function e7($){return $==="TodoWrite"}function $6($){return $==="ExitPlanMode"}function Z6($){return $.startsWith(QW)}function YW($){return Z6($)?$.slice(QW.length):$}function x2($){if(Z6($))return"服务端工具";if(n7($))return"文件变更";if(B3($))return"网页搜索";if(a7($))return"网页读取";if(j3($))return"图片生成";if(o7($))return"读取文件";if(s7($))return"写入文件";if(t7($)||r7($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(e7($))return"更新待办";if($6($))return"确认计划";if($==="Task")return"子任务";return wM($)?"Bash":$}function y1($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(Z6($))return J(vM($,Z),80);if(!Z||typeof Z!=="object")return"";if(d7($))return yM(Z);if(i7($))return fM(Z);if(n7($))return J(gM(Z),80);if(B3($))return J(MW(Z),80);if(a7($))return J(iM(Z),80);if(qQ($))return J(aM(Z),80);if(j3($))return J(sM(Z),80);if(DQ($))return J(tM(Z),80);if(o7($))return J(mM(Z),80);if(s7($))return J(pM(Z),80);if(t7($))return J(cM(Z),80);if(r7($))return J(lM(Z),80);if(FQ($))return J(uM($,Z),80);if(e7($))return J(dM(Z),80);if($6($))return J(_3(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 vM($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:YW($),Q=_3(Z?.input);return Q?`${J}: ${Q}`:J}function yM($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=XW($);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(Y4(Q),46)}`}function VW($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function fM($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${VW($)}${J}`}function XW($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=I5(Z);return{description:Q.description||J,command:Q.command}}function G$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
133
+ `)}function Q3($){let Z=wG.then($);return wG=Z.then(()=>{},()=>{}),Z}async function Y3($,Z,J){HM($,Z),J?.(),DX(),t9()}function vG($,Z){return Q3(()=>Y3($,Z))}async function yG($,Z,J=$.setup){let Q=!1;try{if(!$.configSectionId||!J)throw Error("此来源不支持配置命令");let Y=$.configSectionId,V=()=>{let z=_9().token_sources;return n9({...z,...PJ(z,Y,Z)})[Y]},X=V();await J.validate(X),await Q3(async()=>{if(JSON.stringify(V())!==JSON.stringify(X))throw Error("校验期间账号配置已变化,本次未保存,请重试");await Y3(Y,Z,()=>{Q=!0})})}catch(Y){throw new C7(Y,Q)}}function fG($,Z,J,Q="default"){return Q3(async()=>{let Y=G0($,Q);if(!Y?.enabled||!Y.modelSelection)throw Error("此账号不支持维护可选模型列表");let V=Y.modelSelection.modelIds.filter((j)=>Y.models.find((_)=>_.model===j)?.origin!=="custom");if(J==="add"){if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");let j=Y.modelSelection.availableModels.find((_)=>_.model===Z);if(j?.origin==="custom")throw Error("补录模型请使用删除操作");if(!j||Y.modelSelection.mode!=="catalog"&&(j.unavailableReason||!j.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((j)=>j!==Z),z=m.token_sources[$],H=Y.modelSelection.mode==="catalog",G=r(z?.hidden_models),W=H?{hidden_models:(J==="remove"?[...new Set([...G,Z])]:G.filter((j)=>j!==Z)).join(",")}:{models:X.join(",")};await Y3($,W);let K=G0($,Q);if(K?.modelCatalogState?.status!=="ready")throw Error(`配置已保存,但目录刷新失败:${K?.modelCatalogState?.error??"MISS"}`)})}function hG($,Z,J="default"){return Q3(async()=>{let Q=Z.trim();if(!Q||Q.length>256||/[\s,`<>\\\u0000-\u001f]/.test(Q))throw Error("模型 ID 无效,请只填写一个完整模型名");let Y=G0($,J);if(!Y?.enabled)throw Error("账号不可用");if(Y.validateCustomModelId?.(Q),(Y.modelSelection?.availableModels??Y.models).some((H)=>H.model.toLowerCase()===Q.toLowerCase()))throw Error("模型已在目录或补录记录中;隐藏项请使用“显示”");if(Y.modelCatalogState?.status!=="ready")throw Error(Y.modelCatalogState?.error??"模型目录未就绪");let X=m.token_sources[$];await Y3($,{custom_models:[...r(X?.custom_models),Q].join(",")});let z=G0($,J);if(z?.modelCatalogState?.status!=="ready")throw Error(`补录已保存,但目录刷新失败:${z?.modelCatalogState?.error??"MISS"}`)})}function IG($,Z,J="default"){return Q3(async()=>{let Q=G0($,J),Y=Q?.modelSelection?.availableModels.find((G)=>G.model===Z);if(!Q?.enabled||Y?.origin!=="custom")throw Error("此模型不是补录项,请使用隐藏操作");let V=m.token_sources[$]??{},X=(G)=>G?.trim().replace(/\[1m\]$/,"")===Z.replace(/\[1m\]$/,""),z={custom_models:r(V.custom_models).filter((G)=>!X(G)).join(","),hidden_models:r(V.hidden_models).filter((G)=>!X(G)).join(","),...V.models!==void 0?{models:r(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 Y3($,z);let H=G0($,J);if(H?.modelCatalogState?.status!=="ready")throw Error(`补录已删除,但目录刷新失败:${H?.modelCatalogState?.error??"MISS"}`)})}var wG,C7;var IJ=R(()=>{H0();f0();O7();z0();x0();V1();a9();wG=Promise.resolve();C7=class C7 extends Error{saved;constructor($,Z){super($ instanceof Error?$.message:String($),{cause:$});this.saved=Z}}});var b7={};r$(b7,{runTokenSourceSetup:()=>BM,runClaudeSubscriptionCommand:()=>WM,onTokenSourceEnable:()=>KM});async function WM($,Z){if(Z&&Z!=="on"&&Z!=="off"){await b($.chatId,`用法:${"claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"}`);return}if(Z)try{await vG("claude-sub",{enabled:Z==="on"})}catch(z){let H=z instanceof Error?z.message:String(z);B(`claude-sub ${Z} failed: ${H}`),await b($.chatId,`❌ Claude Code 订阅开关更新失败:${H}`);return}let Q=C0("claude-sub"),Y=m.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"?"模型目录缓存尚未就绪,后台刷新中":"订阅来源不可用")}`);if(X.push("所有群共用;保留本机登录态。"),!Y)X.push("禁止新任务,已在执行的任务继续完成。");X.push("claude-sub 查看状态 · claude-sub on 启用 · claude-sub off 禁用"),await b($.chatId,X.join(`
134
+ `))}async function KM($,Z){let J=C0(Z);if(!J){await b($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled&&J.modelCatalogState?.status!=="failed"){await b($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Q=G2().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup){let Y=J.modelCatalogState?.status==="failed"?`${J.display} 当前不可用:${c0(J.modelCatalogState.error??"MISS")}
135
+ `:"";await b($.chatId,Y+Q.setup.hint(J.display))}else if(J.kind==="codex-subscription"){if(!await n($.chatId,n$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await b($.chatId,m.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 b($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function BM($,Z,J){let Q=G2().find((H)=>H.setup?.commandSuffix===Z||H.usageSetup?.commandSuffix===Z),Y=Q?.usageSetup?.commandSuffix===Z,V=Y?Q?.usageSetup:Q?.setup;if(!Q||!V||!Q.configSectionId){await b($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let X=V.parseArgs(J);if("error"in X){await b($.chatId,X.error);return}await b($.chatId,"正在后台校验账号配置,完成后会返回结果;其他操作可继续使用。");let z=!1;try{await yG(Q,X.config,V),z=!0;let H=C0(Q.configSectionId),G=fH(Q.configSectionId).map((j)=>C0(j)),W=G.find((j)=>(!Y||j?.enabled)&&j?.modelCatalogState?.status!=="ready");if(Y){let j=W?`
136
+ 模型目录仍为 MISS:${c0(W.modelCatalogState?.error??"尚未就绪",[X.config.management_token])}`:"";await b($.chatId,`✅ ${H?.display??Z} 真实余额校验通过,配置已保存。发送 hi 查看;回复页脚使用同一账户余额。${j}`);return}if(W?.modelCatalogState?.status==="failed"||G.some((j)=>!j)){let j=c0(W?.modelCatalogState?.error??"模型目录尚未就绪",[X.config.api_key,X.config.auth_token]);await b($.chatId,`❌ ${H?.display??Z} 凭据校验通过、配置已保存,但暂不可用:${j}
137
+ 处理后等待后台刷新,发送 md 查看状态。`);return}let K=[...new Set(G.filter((j)=>!!j).map((j)=>i0(j.agent)))];await b($.chatId,`✅ ${H.display} 校验通过,配置已保存。${K.length>1?`${K.join(" 和 ")} 共用该账号。`:""}目录与额度在后台刷新;发送 md 查看模型。`)}catch(H){let G=z||H instanceof C7&&H.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",W=c0(H,[X.config.api_key,X.config.auth_token,X.config.management_token]);await b($.chatId,`❌ ${G}:${W}`)}}var k7=R(()=>{$0();z0();IJ();g4();f0();h();a9();_0()});function gG($,Z){let J=Z.catch(async(Q)=>{let Y=`账号操作或结果呈现失败:${x(Q)}`;throw B(Y),await I($.chatId,`❌ ${Y}`),Q});gJ.add(J),J.finally(()=>gJ.delete(J)).catch((Q)=>B(`账号操作结果发送失败:${x(Q)}`))}function mG(){return[...gJ]}async function pG($,Z,J="",Q){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (S7(),hJ));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(() => (S7(),hJ)),j=V[1].toLowerCase(),_=K($,j,(V[2]??"").trim(),J,Q);if(j==="login"||j==="reset")gG($,_);else await _;return!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (k7(),b7));return await K($,(X[1]??"").trim().toLowerCase()),!0}let z=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(z)return await $.runWorktreeCommand((z[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 H=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(H)return await $.runFileDeliveryCommand((H[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(() => (k7(),b7));return gG($,K($,G[1].trim().toLowerCase(),(G[2]??"").trim())),!0}let W=jM.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(),j=$.backendLabel(),_=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${j}`)):null,D=$.withModel(`\uD83D\uDE80 启动 ${j}`);if(!(K?await $.start({announce:!_,onStatus:(L)=>{D=L,$.setStatusCard(_,L)}}):!0))return await $.closeStatusCard(_,D.startsWith("❌")?D:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(_)await $.closeStatusCard(_,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:F}=await Promise.resolve().then(() => (g4(),CG)),U;if(!await n($.chatId,F({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"}),(A)=>{U=A}))throw Error(`额度等待卡片发送失败
138
+ ${w(U)}`)}return!0}if(_)return await $.replaceStatusCardWithConsole(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(_,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let _=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!_,onStatus:(D)=>$.setStatusCard(_,D)}),await $.closeStatusCard(_,"\uD83D\uDED1 已取消额度恢复")}catch(D){throw await $.closeStatusCard(_,`❌ ${x(D)}`),D}return!0}if($.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){if(K)return await $.closeTurnCard("\uD83D\uDED1 已取消未完成的文件上传"),await b($.chatId,"\uD83D\uDED1 已取消未完成的文件上传,已上传文件保留"),!0;let _=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(_)await $.closeStatusCard(_,"⚪ 无正在执行的 turn");else await b($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let j=new Set;for(let[_,D]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(D)g0(_,D);X$(_,"CrossMark"),j.add(_)}for(let _ of $.pendingMidTurnMsgs)if(_.msgId&&!j.has(_.msgId))X$(_.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0}case"kill":{let K=$.isRunning(),j=$.backendLabel($.proc?.provider??$.currentProvider()),_=K?`\uD83D\uDED1 停止 ${j}`:"⚪ session 当前未运行",D=await $.openStatusCard("kill",_,K?"red":"grey"),P=null,L=K?`✅ ${j} 已终止`:`⚪ ${j} 未运行`;try{await $.stop("已终止",{announce:!D,onStatus:(F)=>{$.setStatusCard(D,F)}})}catch(F){P=F,L=$.isRunning()?`❌ ${j} 未确认终止: ${x(F)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${j} 停止收尾失败: ${x(F)}`}finally{try{await $.closeStatusCard(D,L)}catch(F){B(`session "${$.sessionName}": kill status card close failed: ${x(F)}`),await I($.chatId,`${L}
139
+ ⚠️ kill 状态卡片终态写入失败: ${x(F)}`)}}if(P&&!D)await I($.chatId,L)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?S0($.lastSessionId):"",j=$.backendLabel($.proc?.provider??$.currentProvider()),_=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${j}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${j}`),D=await $.openStatusCard("restart",_),P=_,L=await $.restart(!0,{announce:!D,onStatus:(U)=>{P=U,$.setStatusCard(D,U)}}),F=L?P.startsWith("✅")?P:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):P.startsWith("❌")?P:"❌ 重启失败";await $.closeStatusCard(D,L?$.withModel(F):F)}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 b($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let K=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),j="\uD83E\uDDF9 清空并启动新会话",_=await $.restart(!1,{announce:!K,onStatus:(D)=>{j=D,$.setStatusCard(K,D)}});await $.closeStatusCard(K,_?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):j.startsWith("❌")?j:"❌ 清空失败")}return!0}}var jM,gJ;var mJ=R(()=>{$0();h();jM=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"]]),gJ=new Set});function E0($,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 E2($){switch($){case"project":return"项目任务";case"delegated":return"委派任务";case"subagent":return"子 Agent";case"background":return"后台进程"}}function lG($){switch($){case"project":return"\uD83D\uDCC2";case"delegated":return"\uD83E\uDDE0";case"subagent":return"\uD83E\uDD16";case"background":return"⚙️"}}var cG;var pJ=R(()=>{cG=["delegated","project","subagent","background"]});function V3($,Z=360){let J=$.replace(/\s+/g," ").trim();if(!J)return"说明 MISS";if(J.length<=Z)return J;let Q="_任务内容已精简,完整内容仅用于执行。_",Y=Math.max(1,Z-Q.length-2);return`${J.slice(0,Y)}…
140
+
141
+ ${Q}`}function w7($,Z=8000){if($.length<=Z)return $;let J="_结果超过卡片安全上限,已截断。_",Q=Math.max(1,Z-J.length-2);return`${$.slice(0,Q)}…
142
+
143
+ ${J}`}function uG($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function LM($,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 dG($){return $==="workflow"||$==="monitor"}function D$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function lJ($){return $.some((Z)=>!D$(Z))}function z3($,Z,J=Date.now()){let Q=LM(Z.task_type,Z.subagent_type),Y=(H)=>H.id===Z.task_id||!!Z.tool_use_id&&H.toolUseId===Z.tool_use_id,V=$.active.some(Y),X=$.pending.some(Y);if(V||X){let H=(G)=>({...G,...D$(G)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type:Q==="unknown"?G.type:Q,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&&Q==="subagent")return{active:[...$.active,...$.pending.filter(Y).map(H)],pending:$.pending.filter((G)=>!Y(G))};return{active:V?$.active.map((G)=>Y(G)?H(G):G):$.active,pending:X?$.pending.map((G)=>Y(G)?H(G):G):$.pending}}let z={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:[],...dG(Q)?{isBackgrounded:!0}:{}};return Q==="subagent"||dG(Q)?{active:[...$.active,z],pending:$.pending}:{active:$.active,pending:[...$.pending,z]}}function uJ($,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 dJ($,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],z={...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,z],pending:$.pending.filter((H)=>H.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Y||V){let X=(z)=>({...z,status:Q.status??z.status,description:Q.description??z.description,error:Q.error??z.error,isBackgrounded:Q.is_backgrounded??z.isBackgrounded,endTime:Q.end_time??z.endTime});return{active:Y?$.active.map((z)=>z.id===Z.task_id?X(z):z):$.active,pending:V?$.pending.map((z)=>z.id===Z.task_id?X(z):z):$.pending}}return $}function iJ($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function y7($,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 v7($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>PM){J=Q+1;break}return J===0?$:$.slice(J)}function qM($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return Y4(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 DM($,Z){let Q=((typeof $==="string"?$:Array.isArray($)?$.map((Y)=>typeof Y?.text==="string"?Y.text:JSON.stringify(Y)).join(`
144
+ `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Q.slice(0,80)}`:Q.slice(0,80)}function nJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((H)=>H.toolUseId===Z),X=$.pending.some((H)=>H.toolUseId===Z);if(!V&&!X)return $;let z=(H)=>H.map((G)=>G.toolUseId===Z?{...G,steps:v7([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${qM(Q,Y)}`.trim()}])}:G);return{active:V?z($.active):$.active,pending:X?z($.pending):$.pending}}function aJ($,Z,J,Q,Y,V){let X=$.active.some((G)=>G.id===Z),z=$.pending.some((G)=>G.id===Z);if(!X&&!z)return $;let H=(G)=>G.map((W)=>{if(W.id!==Z)return W;if(Y==="started")return{...W,steps:v7([...W.steps,{toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()}])};let K=!1,j=W.steps.map((_)=>{if(K||_.toolUseId!==J)return _;return K=!0,{..._,brief:V?`${_.brief} ${V}`:_.brief}});if(!K&&V)j.push({toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()});return{...W,steps:v7(j)}});return{active:X?H($.active):$.active,pending:z?H($.pending):$.pending}}function oJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((H)=>H.toolUseId===Z),X=$.pending.some((H)=>H.toolUseId===Z);if(!V&&!X)return $;let z=(H)=>H.map((G)=>{if(G.toolUseId!==Z)return G;let W=!1,K=G.steps.map((j)=>{if(W||j.toolUseId!==J)return j;return W=!0,{...j,brief:`${j.brief} → ${DM(Q,Y)}`}});return{...G,steps:v7(K)}});return{active:V?z($.active):$.active,pending:X?z($.pending):$.pending}}function H3($){return $.type==="subagent"?"subagent":"background"}function sG($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of FM)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:`${E0((Q+1)*600,"down")}+`,nextDelayMs:Y-Z}}function p4($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=cJ){let Q=Math.floor((J-cJ)/iG),Y=cJ+(Q+1)*iG;return{label:`${E0((10+Q*5)*60,"down")}+`,nextDelayMs:Y-J}}return{label:E0(Math.floor(J/1000)),nextDelayMs:oG}}return sG($)}function nG($){return $.subagentType??$.workflowName??aG[$.type]}function UM($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function MM($){let Z=E2(H3($)),J=aG[$.type],Q=[`**${Z}${J!==Z?` · ${J}`:""}**${nG($)!==J?` · ${nG($)}`:""}${D$($)?` · 用时 ${E0(UM($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Q.push(`⚠ ${$.error}`);if($.summary)Q.push("",`**${D$($)?"结果":"进度"}**`,D$($)?w7($.summary):V3($.summary));if($.prompt)Q.push("","**任务说明**",V3($.prompt));if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3))Q.push(`- ${Y.brief}`)}else if($.lastToolName)Q.push("",`最近动作:${$.lastToolName}`);return Q0(Q.join(`
145
+ `))}function f7($){let Z=E2(H3($)),J={running:`⏳ ${Z}正在执行`,pending:`⏳ ${Z}等待执行`,paused:`⏸️ ${Z}已暂停`,completed:`✅ ${Z}完成`,failed:`❌ ${Z}失败`,killed:`\uD83D\uDED1 ${Z}已终止`}[$.status],Q=$.description.replace(/\s+/g," ").trim()||"说明 MISS";return`${J} · ${Q.length<=40?Q:`${Q.slice(0,39)}…`}`}function sJ($){return{tag:"collapsible_panel",element_id:X3.panel($.id),header:{title:{tag:"plain_text",content:f7($)}},expanded:!1,elements:[{tag:"markdown",element_id:X3.body($.id),content:MM($)}]}}var X3,PM=1000,aG,FM,oG=1000,cJ=600000,iG=300000;var tJ=R(()=>{h0();F8();pJ();X3={panel:($)=>`bg_${uG($)}`,body:($)=>`bgb_${uG($)}`};aG={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"};FM=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as OM}from"node:events";import{join as AM,isAbsolute as NM,extname as RM,basename as TM}from"node:path";import{readFile as EM}from"node:fs/promises";function xM($){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 h7=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),rJ,eJ;var tG=R(()=>{_0();e1();s9();h();rJ={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};eJ=class eJ extends OM{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=h7();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"};M0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new U7({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:AM($.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,allowUserInput:this.opts.allowUserInput!==!1,...this.opts.profile?.tools?{allowedTools:this.opts.profile.tools.split(",").map((Z)=>{let J=Z.trim();return Object.keys(rJ).find((Q)=>rJ[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)=>!NM(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(`
146
+ `)}],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(RM(V).toLowerCase()))continue;let X=await EM(V);J.push({type:"image",mediaType:xM(X),name:TM(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((z)=>{let H=V?.[z.question]??V?.[z.id];if(typeof H!=="string")throw Error(`missing answer to DSH question: ${z.question}`);let G=z.options?.find((W)=>W.label===H);return{id:z.id,selected:G?[H]:[],...G?{}:{custom:H}}}):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((z)=>this.fail(z))}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(!O0(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 K2}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={...h7(),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}
147
+
148
+ ${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=h7(),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=rJ[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={...h7(),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})}}});import{EventEmitter as SM}from"node:events";function kM($,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 CM="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",bM,$Q=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),ZQ;var rG=R(()=>{j0();w8();J$();h();bM=["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"];ZQ=class ZQ extends SM{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??$Q()}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??W2}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((X)=>`${X.account.name}:${X.reason??X.state}`).join(";");if(Q.retryAt===void 0){let z=Q.candidates.some((H)=>H.state==="miss"&&!H.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()));B(`codex account: waiting for quota: ${Y}`),this.notice("暂无可用账号 · 自动等待恢复",V),this.resolveQuotaWait(),await(this.opts.wait??kM)(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,O1(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((H)=>H.usage!==null&&H.state==="miss"&&!H.duplicateOf).map((H)=>`${H.account.name}:${H.reason}`)}),this.lifetime.signal.throwIfAborted(),V.sendInitialize();let z=V.initializationPromise?.();if(!z)throw Error("Codex 初始化未提供确认事务");if(await z,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($){let Z=null;for(let J of bM)$.on(J,(...Q)=>{if(this.inner===$&&!this.closed){if(J==="token_usage"&&Z&&Q[0]?.turnId===Z&&Q[0]?.threadId===$.sessionId&&Q[0]?.usage&&Object.values(Q[0].usage).some((Y)=>typeof Y==="number"&&Number.isFinite(Y)&&Y>0)&&this.selected)this.scheduler().recordUsage(this.selected.account.id,this.lastModel||this.opts.model);if(J==="bg_task_started")this.backgroundTasks.add(Q[0].task_id);if(J==="bg_task_settled")this.backgroundTasks.delete(Q[0].task_id);this.emit(J,...Q)}});$.on("turn_retry",(J)=>{if(this.inner===$&&!this.closed)this.emit("turn_retry",J)}),$.on("turn_started",(J)=>{if(this.inner!==$||this.closed)return;Z=J.turn_id,this.result=null,this.ownRetry=null;let Q=this.retryTurn||J.retry;this.retryTurn=!1,this.emit("turn_started",{...J,...Q?{retry:!0}:{}})}),$.on("result",(J)=>{if(this.inner!==$||this.closed||this.lifetime.signal.aborted)return;if(Z=null,J?.is_error&&J.codexQuotaFailure&&!this.recovery){this.retryCount++;let Q=Promise.resolve().then(()=>this.recover($,J.codexQuotaFailure)).catch((Y)=>{if(!this.lifetime.signal.aborted)this.fail(Y)}).finally(()=>{if(this.recovery===Q)this.recovery=null});this.recovery=Q,this.notice(`「${this.selected?.account.name??"MISS"}」额度耗尽 · 正在换号续跑`);return}if(this.recovery)return;this.retryCount=0,this.result=null,this.emit("result",J)}),$.on("exit",(J)=>{if(this.inner!==$||this.closed)return;if((this.recovery||this.shutdown)&&J.expected)return;this.lifetime.abort(Error("Codex 进程退出")),this.closed=!0,this.emit("exit",J)})}async recover($,Z){if(this.lifetime.signal.throwIfAborted(),!this.selected)throw Error("额度耗尽时未记录运行账号");let J=z2(this.selected.account.id);if(J?.state==="ok")this.selected={...this.selected,usage:J,identity:J.accountFingerprint??this.selected.identity};let Q=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 V=$.isConversationResumable?.()===!0&&$.sessionId;if(Z.accepted&&!V)throw Error("额度耗尽后未确认原会话落盘,不能重放已执行的任务");if(!Z.accepted&&typeof Z.rejectedInput!=="string")throw Error("额度耗尽的拒绝响应缺少原始输入");let X=V?{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(X,void 0,Q),this.lifetime.signal.throwIfAborted(),this.retryTurn=!0,this.notice(`已切换「${this.selected.account.name}」· 继续原任务`),this.lifetime.signal.throwIfAborted();let z=Z.accepted?CM:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(z),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...$Q(),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={...$Q(),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 G3($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new ZQ({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,j,_,D,P)=>G3({...$,model:D,effort:P,codexAccountPreference:void 0,codexManualAccount:_,codexAccountId:K,launch:j})}),sourceRevision:null}}let Z=$.codexAccountId??l,J=G0($.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=G4(J,Y),X=!Q&&J&&I$(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 z=!Q&&J&&Y?J.resolveSpawnModel(Y):Y;if(Y&&!z)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Y}`);let H=J?(W)=>J.spawnEnv(W,z):void 0;if($.provider==="dsh"){if(!J||!z||!O0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new eJ({...$,model:z,effort:$.effort,tokenSourceId:J.id,transformEnv:H}),sourceRevision:V}}if($.provider==="claude"){if(BZ(),!R0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new m8({workDir:$.workDir,model:z,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}:{},...$.allowUserInput===!1?{allowUserInput:!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:H,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!_$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let G=new z4({workDir:$.workDir,model:z,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},...$.allowUserInput===!1?{allowUserInput:!1}:{},tokenSourceId:J?.id??null,transformEnv:H,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z,...J?.codexApiProvider?{apiProvider:J.codexApiProvider}:{}});if(!J?.codexApiProvider)O1(G,Z);return{process:G,sourceRevision:V}}var JQ=R(()=>{_0();tG();_4();J1();z0();j0();rG()});function c4($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function eG($){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 x2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function QQ($){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 vM($){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 yM($){let Z=x2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${QQ($.file.url)})`:Z,Q=$.status==="failed"?`<font color='red'>${x2($.error??"交付失败")}</font>`:`<font color='grey'>${eG($.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:vM($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
149
+ ${Q}`}]}]}}function YQ($){let Z=$.files.filter((H)=>H.status==="ready").length,J=$.files.filter((H)=>H.status==="failed").length,Q=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Y=$.folderAccessReady&&$.folder?QQ($.folder.url):void 0,V=[...$.files.filter((H)=>H.status==="failed"),...$.files.filter((H)=>H.status!=="failed")],X=V.slice(0,wM),z=V.slice(X.length).filter((H)=>H.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:C.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(yM),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${z?`中有 ${z} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${x2($.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 VQ($){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}**
150
+ 工作目录:${x2($.workDir)}
151
+ 群:${x2($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:x2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${x2($.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:QQ($.settings.folder.url)}]}]:[]]}}}var wM=12;var I7=R(()=>{h0()});function g7($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function m7($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function fM($,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 ZW($,Z,J){let Q=fM($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function $W($){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 p7($,Z){let J=$W($);return Z!=null&&Z>0?`${J}/${$W(Z)}`:`${J}/--`}function JW($,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 zQ($,Z,J){let Q=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Q||"MISS"}/${J||"MISS"}`}function l7($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function hM($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function IM($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function c7($){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 QW($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function VW($){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 gM($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${VW($)}`}function XQ($){return typeof $==="number"&&Number.isFinite($)?$:null}function mM($){let Z=XQ($.startedAtMs),J=XQ($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${E0((J-Z)/1000)}`}function pM($){let Z=XQ($);return Z==null?null:c7(Z)}function cM($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=pM($.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 HQ($,Z,J){if($==null||!Number.isFinite($))return null;let Q=ZW($,Z,J);return Q?`${Q.used}% · ${p7($,Z)}`:"--"}function GQ($){let Z=c7($?.input_tokens??Number.NaN),J=c7($?.cache_read_input_tokens??Number.NaN),Q=c7($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function W3($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",V=Y?"✅":"⏳",X=Y?mM(Q):"",z=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,H=cM(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:z}},expanded:!1,elements:[{tag:"markdown",content:H.join(`
152
+ `)}]}}function XW($,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(`- ${hM(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(`
153
+ `)}function WQ($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:gM($,J)}},expanded:!1,elements:[{tag:"markdown",content:XW($,Z,J)}]}}function K3($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${VW($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:XW($,Z)}]}}function KQ($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${QW($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${E0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${QW($.status)}: ${IM($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
154
+ `)}]}}function u7($){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:C.userInput,header:{title:{tag:"plain_text",content:Y}},expanded:!1,elements:Q.map((X)=>({tag:"markdown",content:Q0(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:C.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function zW($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function lM($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function uM($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let V=$.options[Y],X=V.description?` · ${Q0(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:`**${Q0(V.label)}**${X}`}]})}return Q}function YW($,Z,J,Q){if($.length===0)return null;let Y=$.length,V=[];for(let X=0;X<$.length;X++){let z=$[X];if(!z)continue;let H=zW(z,X,Y),G=Q.get(X);if(G){let W=lM(z,G),K=[`**✅ ${H}**`,`**回答**:${W}`];V.push({tag:"markdown",content:K.join(`
155
+ `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${H}**`}),z.options.length>0)V.push(...uM(z,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${H}**`})}return V}function l4($,Z,J,Q="\uD83E\uDD14",Y){let V=J.length,X=Y?.answered??new Map,z=Y?.currentIdx,H=z===void 0&&X.size>0,G=[],W;if(Y?.waitingFor)W=Y.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",G.push({tag:"markdown",content:Y.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(H){W=`${Q} 已回答 · ${V}/${V}`,G.push(...YW(J,Z,z,X)??[]);let K=[...X.values()].reverse().find((j)=>j.user)?.user;if(K)G.push({tag:"markdown",content:`
156
+ *— 由 ${K} 回答*`})}else if(z!==void 0&&J[z])W=`${Q} 等你确认 · ${z+1}/${V}`,G.push(...YW(J,Z,z,X)??[]);else if(W=`${Q} 等你确认`,J[0])G.push({tag:"markdown",content:`**${zW(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!H&&!Y?.waitingFor,elements:G}}var HW=R(()=>{h0()});import{isAbsolute as BQ,relative as dM}from"node:path";function i7($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function n7($){return $==="write_stdin"||$.endsWith(".write_stdin")}function nM($){return i7($)||n7($)}function a7($){return $==="FileChange"||$==="fileChange"}function j3($){return $==="WebSearch"||$==="webSearch"}function o7($){return $==="WebFetch"||$==="webFetch"}function DQ($){return $==="MCP"}function _3($){return $==="ImageGeneration"||$==="imageGeneration"}function FQ($){return $==="Agent"||$==="Task"}function s7($){return $==="Read"}function t7($){return $==="Write"}function r7($){return $==="Edit"||$==="NotebookEdit"}function e7($){return $==="MultiEdit"}function UQ($){return $==="Glob"||$==="Grep"||$==="LS"}function $6($){return $==="TodoWrite"}function Z6($){return $==="ExitPlanMode"}function J6($){return $.startsWith(WW)}function KW($){return J6($)?$.slice(WW.length):$}function S2($){if(J6($))return"服务端工具";if(a7($))return"文件变更";if(j3($))return"网页搜索";if(o7($))return"网页读取";if(_3($))return"图片生成";if(s7($))return"读取文件";if(t7($))return"写入文件";if(r7($)||e7($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if($6($))return"更新待办";if(Z6($))return"确认计划";if($==="Task")return"子任务";return nM($)?"Bash":$}function y1($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(J6($))return J(aM($,Z),80);if(!Z||typeof Z!=="object")return"";if(i7($))return oM(Z);if(n7($))return sM(Z);if(a7($))return J(eM(Z),80);if(j3($))return J(xW(Z),80);if(o7($))return J(XO(Z),80);if(DQ($))return J(HO(Z),80);if(_3($))return J(WO(Z),80);if(FQ($))return J(KO(Z),80);if(s7($))return J($O(Z),80);if(t7($))return J(ZO(Z),80);if(r7($))return J(JO(Z),80);if(e7($))return J(QO(Z),80);if(UQ($))return J(YO($,Z),80);if($6($))return J(VO(Z),80);if(Z6($))return J(L3(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 aM($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:KW($),Q=L3(Z?.input);return Q?`${J}: ${Q}`:J}function oM($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=jW($);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(Y4(Q),46)}`}function BW($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function sM($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${BW($)}${J}`}function jW($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=g5(Z);return{description:Q.description||J,command:Q.command}}function G$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
156
157
  ${$}
157
- ${J}`}function K1($,Z=kM,J=""){if($.length<=Z)return G$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,G$(`${Q}
158
+ ${J}`}function K1($,Z=iM,J=""){if($.length<=Z)return G$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,G$(`${Q}
158
159
  ... output 已截断 ...`,J)].join(`
159
- `)}function l($){return"`"+String($??"").replace(/`/g,"'")+"`"}function F$($,Z=3000){return G$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function _3($){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 zW($,Z,J){let Q=XW($),Y=Q.command,V=Q.description,X=[];if(V)X.push(`**目的**: ${V}`);let z=$?.cwd??$?.workdir;if(z)X.push(`**cwd**: ${l(z)}`);if($?.source)X.push(`**source**: ${l($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(G$(Y||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(K1(Z));return X.join(`
160
- `)}function HW($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${VW($)}`),Y!==void 0)Q.push(`**session**: ${l(Y)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Q.push(""),Q.push("**输入**"),Q.push(G$(V))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(K1(Z));return Q.join(`
161
- `)}function GW($){return Array.isArray($?.changes)?$.changes:[]}function WW($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function K3($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&KQ(J)&&KQ(Z)){let Q=bM(Z,J);if(Q&&!Q.startsWith("..")&&!KQ(Q))return Q}return J}function hM($){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 KW($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function jQ($){let Z=hM($);if(KW($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function _Q($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function PQ($){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 BW($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function LQ($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function IM($){return $.length>1800?$.slice(0,1800)+`
162
- ... diff 已截断 ...`:$}function gM($){let Z=GW($),J=WW($);if(Z.length===0){let H=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?K3($.grantRoot):"";if(H&&G)return`${H} · ${G}`;return H||(G?`申请修改 ${G}`:"")}let Q=Z.map((H)=>PQ(_Q(H))).reduce(BW,{added:0,removed:0}),Y=LQ(Q),V=[...new Set(Z.map(jQ))],X=K3(Z[0]?.path,J),z=Y?` · ${Y}`:"";if(Z.length===1)return`${V[0]} ${X}${z}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${z}`}function jW($,Z,J){let Q=GW($),Y=WW($),V=[];if(Q.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)V.push(`**原因**: ${G}`);if($?.grantRoot)V.push(`**范围**: ${l(K3($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(G$(Z.slice(0,3000)));return V.length>0?V.join(`
163
- `):G$(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((G)=>PQ(_Q(G))).reduce(BW,{added:0,removed:0}),z=LQ(X);if(V.push(`**文件**: ${Q.length} 个`),z)V.push(`**行数**: ${z}`);if($?.status)V.push(`**状态**: ${l($.status)}`);let H=Q.slice(0,5);for(let G of H){let W=_Q(G),K=LQ(PQ(W)),j=K3(G?.path,Y),_=K?`**${jQ(G)}** ${l(j)} · ${K}`:`**${jQ(G)}** ${l(j)}`;V.push(""),V.push(_);let D=KW(G);if(D)V.push(`来自 ${l(K3(D,Y))}`);V.push(W?G$(IM(W),"diff"):"_无 diff 内容_")}if(Q.length>H.length)V.push(""),V.push(`还有 ${Q.length-H.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
164
- `)}function f1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function mM($){let Z=f1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function pM($){let Z=f1($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function cM($){let Z=f1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function lM($){let Z=f1($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function uM($,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 _W($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function dM($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let V=_W(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 iM($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function u4($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(K1(Z,1200))}function PW($,Z,J){let Q=[],Y=f1($);if(Y)Q.push(`**路径**: ${l(Y)}`);if($?.offset!=null)Q.push(`**offset**: ${l($.offset)}`);if($?.limit!=null)Q.push(`**limit**: ${l($.limit)}`);if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("_内容已读取,未展开到群聊卡片。_");return Q.length>0?Q.join(`
165
- `):F$($??{},2000)}function LW($,Z,J){let Q=[],Y=f1($),V=typeof $?.content==="string"?$.content:"";if(Y)Q.push(`**路径**: ${l(Y)}`);if(V){let X=V.split(/\r?\n/).length;Q.push(`**内容**: ${X} 行 / ${V.length} 字符`),Q.push(K1(V,1200))}if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.length>0?Q.join(`
166
- `):F$($??{},2000)}function qW($,Z,J){let Q=[],Y=f1($);if(Y)Q.push(`**路径**: ${l(Y)}`);if($?.cell_id)Q.push(`**cell**: ${l($.cell_id)}`);if($?.edit_mode)Q.push(`**模式**: ${l($.edit_mode)}`);if($?.replace_all)Q.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Q.push(""),Q.push("**查找**"),Q.push(K1($.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(K1(V,800));if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.length>0?Q.join(`
167
- `):F$($??{},2000)}function DW($,Z,J){let Q=[],Y=f1($),V=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${l(Y)}`);Q.push(`**编辑**: ${V.length} 处`);for(let[X,z]of V.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${X+1}${z?.replace_all?" · 全局替换":""}**`),typeof z?.old_string==="string")Q.push("查找:"),Q.push(K1(z.old_string,500));if(typeof z?.new_string==="string")Q.push("替换为:"),Q.push(K1(z.new_string,500))}if(V.length>5)Q.push(""),Q.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.join(`
168
- `)}function FW($,Z,J,Q){let Y=[];if($==="Glob"){if(Y.push("**动作**: 匹配文件"),Z?.pattern)Y.push(`**pattern**: ${l(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${l(Z.path)}`)}else if($==="Grep"){if(Y.push("**动作**: 搜索文件"),Z?.pattern)Y.push(`**pattern**: ${l(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${l(Z.path)}`);if(Z?.glob)Y.push(`**glob**: ${l(Z.glob)}`);if(Z?.type)Y.push(`**type**: ${l(Z.type)}`);if(Z?.output_mode)Y.push(`**output**: ${l(Z.output_mode)}`)}else{if(Y.push("**动作**: 列目录"),Z?.path)Y.push(`**path**: ${l(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Y.push(`**ignore**: ${Z.ignore.map(l).join(" ")}`)}if(Q)Y.push(""),Y.push(Q);return u4(Y,J),Y.join(`
169
- `)}function UW($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let V of Q.slice(0,12)){let X=_W(V?.status),z=String(V?.content??V?.activeForm??"").trim()||"(空)";Y.push(`- ${X}: ${z}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return u4(Y,Z),Y.join(`
170
- `)}function UQ($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function MQ($,Z){return UQ(Z)??$?.action??{}}function OQ($,Z){let J=MQ($,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 AQ($,Z){let J=MQ($,Z);return String(J?.url??$?.url??"")}function MW($){let Z=OQ($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=AQ($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function nM($,Z){let J=OQ($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=AQ($,Z);if(Q)return Q;return MW($)}function OW($,Z,J){let Q=MQ($,Z),Y=OQ($,Z),V=AQ($,Z),X=[],z=typeof Q?.type==="string"?Q.type:"";if(z==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let H of Y.slice(0,6))X.push(`- ${l(H)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(z==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${l(V)}`)}else if(z==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${l(V)}`);if(Q?.pattern)X.push(`**关键词**: ${l(Q.pattern)}`)}else if(X.push(`**动作**: ${z?l(z):"网页搜索"}`),V)X.push(`**URL**: ${l(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(G$(Z.slice(0,3000),"json"));return X.join(`
171
- `)}function AW($,Z,J){let Q=["**动作**: 读取网页"];if($?.url)Q.push(`**URL**: ${l($.url)}`);if($?.prompt)Q.push(""),Q.push("**问题**"),Q.push(String($.prompt).slice(0,1200));if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.join(`
172
- `)}function aM($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=_3($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function NW($,Z,J){let Q=[];if($?.server)Q.push(`**server**: ${l($.server)}`);if($?.tool)Q.push(`**tool**: ${l($.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(F$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let V=UQ(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((z)=>typeof z?.text==="string"?z.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
160
+ `)}function u($){return"`"+String($??"").replace(/`/g,"'")+"`"}function F$($,Z=3000){return G$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function L3($){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 _W($,Z,J){let Q=jW($),Y=Q.command,V=Q.description,X=[];if(V)X.push(`**目的**: ${V}`);let z=$?.cwd??$?.workdir;if(z)X.push(`**cwd**: ${u(z)}`);if($?.source)X.push(`**source**: ${u($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(G$(Y||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(K1(Z));return X.join(`
161
+ `)}function LW($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${BW($)}`),Y!==void 0)Q.push(`**session**: ${u(Y)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let V=$.chars==="\x03"?"^C":$.chars;Q.push(""),Q.push("**输入**"),Q.push(G$(V))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(K1(Z));return Q.join(`
162
+ `)}function PW($){return Array.isArray($?.changes)?$.changes:[]}function qW($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function B3($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&BQ(J)&&BQ(Z)){let Q=dM(Z,J);if(Q&&!Q.startsWith("..")&&!BQ(Q))return Q}return J}function tM($){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 DW($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function _Q($){let Z=tM($);if(DW($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function LQ($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function PQ($){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 FW($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function qQ($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function rM($){return $.length>1800?$.slice(0,1800)+`
163
+ ... diff 已截断 ...`:$}function eM($){let Z=PW($),J=qW($);if(Z.length===0){let H=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?B3($.grantRoot):"";if(H&&G)return`${H} · ${G}`;return H||(G?`申请修改 ${G}`:"")}let Q=Z.map((H)=>PQ(LQ(H))).reduce(FW,{added:0,removed:0}),Y=qQ(Q),V=[...new Set(Z.map(_Q))],X=B3(Z[0]?.path,J),z=Y?` · ${Y}`:"";if(Z.length===1)return`${V[0]} ${X}${z}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${z}`}function UW($,Z,J){let Q=PW($),Y=qW($),V=[];if(Q.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)V.push(`**原因**: ${G}`);if($?.grantRoot)V.push(`**范围**: ${u(B3($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(G$(Z.slice(0,3000)));return V.length>0?V.join(`
164
+ `):G$(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((G)=>PQ(LQ(G))).reduce(FW,{added:0,removed:0}),z=qQ(X);if(V.push(`**文件**: ${Q.length} 个`),z)V.push(`**行数**: ${z}`);if($?.status)V.push(`**状态**: ${u($.status)}`);let H=Q.slice(0,5);for(let G of H){let W=LQ(G),K=qQ(PQ(W)),j=B3(G?.path,Y),_=K?`**${_Q(G)}** ${u(j)} · ${K}`:`**${_Q(G)}** ${u(j)}`;V.push(""),V.push(_);let D=DW(G);if(D)V.push(`来自 ${u(B3(D,Y))}`);V.push(W?G$(rM(W),"diff"):"_无 diff 内容_")}if(Q.length>H.length)V.push(""),V.push(`还有 ${Q.length-H.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
165
+ `)}function f1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function $O($){let Z=f1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function ZO($){let Z=f1($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function JO($){let Z=f1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function QO($){let Z=f1($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function YO($,Z){if($==="Glob"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}if($==="Grep"){let J=String(Z?.pattern??"");return Z?.path?`${J} · ${Z.path}`:J}return String(Z?.path??"")}function MW($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function VO($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let V=MW(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 XO($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function u4($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(K1(Z,1200))}function OW($,Z,J){let Q=[],Y=f1($);if(Y)Q.push(`**路径**: ${u(Y)}`);if($?.offset!=null)Q.push(`**offset**: ${u($.offset)}`);if($?.limit!=null)Q.push(`**limit**: ${u($.limit)}`);if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("_内容已读取,未展开到群聊卡片。_");return Q.length>0?Q.join(`
166
+ `):F$($??{},2000)}function AW($,Z,J){let Q=[],Y=f1($),V=typeof $?.content==="string"?$.content:"";if(Y)Q.push(`**路径**: ${u(Y)}`);if(V){let X=V.split(/\r?\n/).length;Q.push(`**内容**: ${X} 行 / ${V.length} 字符`),Q.push(K1(V,1200))}if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.length>0?Q.join(`
167
+ `):F$($??{},2000)}function NW($,Z,J){let Q=[],Y=f1($);if(Y)Q.push(`**路径**: ${u(Y)}`);if($?.cell_id)Q.push(`**cell**: ${u($.cell_id)}`);if($?.edit_mode)Q.push(`**模式**: ${u($.edit_mode)}`);if($?.replace_all)Q.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Q.push(""),Q.push("**查找**"),Q.push(K1($.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(K1(V,800));if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.length>0?Q.join(`
168
+ `):F$($??{},2000)}function RW($,Z,J){let Q=[],Y=f1($),V=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${u(Y)}`);Q.push(`**编辑**: ${V.length} 处`);for(let[X,z]of V.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${X+1}${z?.replace_all?" · 全局替换":""}**`),typeof z?.old_string==="string")Q.push("查找:"),Q.push(K1(z.old_string,500));if(typeof z?.new_string==="string")Q.push("替换为:"),Q.push(K1(z.new_string,500))}if(V.length>5)Q.push(""),Q.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.join(`
169
+ `)}function TW($,Z,J,Q){let Y=[];if($==="Glob"){if(Y.push("**动作**: 匹配文件"),Z?.pattern)Y.push(`**pattern**: ${u(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${u(Z.path)}`)}else if($==="Grep"){if(Y.push("**动作**: 搜索文件"),Z?.pattern)Y.push(`**pattern**: ${u(Z.pattern)}`);if(Z?.path)Y.push(`**path**: ${u(Z.path)}`);if(Z?.glob)Y.push(`**glob**: ${u(Z.glob)}`);if(Z?.type)Y.push(`**type**: ${u(Z.type)}`);if(Z?.output_mode)Y.push(`**output**: ${u(Z.output_mode)}`)}else{if(Y.push("**动作**: 列目录"),Z?.path)Y.push(`**path**: ${u(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Y.push(`**ignore**: ${Z.ignore.map(u).join(" ")}`)}if(Q)Y.push(""),Y.push(Q);return u4(Y,J),Y.join(`
170
+ `)}function EW($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let V of Q.slice(0,12)){let X=MW(V?.status),z=String(V?.content??V?.activeForm??"").trim()||"(空)";Y.push(`- ${X}: ${z}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return u4(Y,Z),Y.join(`
171
+ `)}function MQ($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function OQ($,Z){return MQ(Z)??$?.action??{}}function AQ($,Z){let J=OQ($,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 NQ($,Z){let J=OQ($,Z);return String(J?.url??$?.url??"")}function xW($){let Z=AQ($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=NQ($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function zO($,Z){let J=AQ($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=NQ($,Z);if(Q)return Q;return xW($)}function SW($,Z,J){let Q=OQ($,Z),Y=AQ($,Z),V=NQ($,Z),X=[],z=typeof Q?.type==="string"?Q.type:"";if(z==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let H of Y.slice(0,6))X.push(`- ${u(H)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(z==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${u(V)}`)}else if(z==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${u(V)}`);if(Q?.pattern)X.push(`**关键词**: ${u(Q.pattern)}`)}else if(X.push(`**动作**: ${z?u(z):"网页搜索"}`),V)X.push(`**URL**: ${u(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(G$(Z.slice(0,3000),"json"));return X.join(`
172
+ `)}function CW($,Z,J){let Q=["**动作**: 读取网页"];if($?.url)Q.push(`**URL**: ${u($.url)}`);if($?.prompt)Q.push(""),Q.push("**问题**"),Q.push(String($.prompt).slice(0,1200));if(J)Q.push(""),Q.push(J);return u4(Q,Z),Q.join(`
173
+ `)}function HO($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=L3($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function bW($,Z,J){let Q=[];if($?.server)Q.push(`**server**: ${u($.server)}`);if($?.tool)Q.push(`**tool**: ${u($.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(F$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let V=MQ(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((z)=>typeof z?.text==="string"?z.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
173
174
  `).slice(0,3000));if(V.structuredContent)Q.push(""),Q.push("**structuredContent**"),Q.push(F$(V.structuredContent,2000));if(X.length===0&&!V.structuredContent)Q.push(F$(V,3000))}else Q.push(V?F$(V,3000):G$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
174
- `):F$($??{},2000)}function oM($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${l(typeof Z?.tool==="string"&&Z.tool?Z.tool:YW($))}`],V=Z?.input;if(V&&typeof V==="object")if(Y.push(""),Y.push("**input**"),Object.keys(V).length>0)Y.push(F$(V,2000));else Y.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Y.push(`**input**: ${l(V)}`);if(Q)Y.push(""),Y.push(Q);if(J!=null)Y.push(""),Y.push("---"),Y.push("**结果**"),Y.push(K1(J,3000));return Y.join(`
175
- `)}function sM($){return typeof $?.status==="string"?$.status:""}function RW($,Z,J,Q){let Y=[];if($?.status)Y.push(`**状态**: ${l($.status)}`);if($?.prompt)Y.push("","**提示词**",G$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Y.push("",$.prompt?"**实际提示词**":"**提示词**",G$(String($.revisedPrompt)))}if(J)Y.push(""),Y.push(J);if(!Q&&Z!=null&&Z.trim())Y.push(""),Y.push("---"),Y.push("**输出**"),Y.push(l(Z.trim()));return Y.length>0?Y.join(`
176
- `):F$($??{},2000)}function tM($){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 u7($,Z,J){let Q=[];if($?.tool)Q.push(`**tool**: ${l($.tool)}`);if($?.model)Q.push(`**model**: ${l($.model)}`);if($?.description)Q.push(`**描述**: ${$.description}`);if($?.subagent_type)Q.push(`**类型**: ${l($.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=UQ(Z);Q.push(Y?F$(Y,3000):G$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
177
- `):F$($??{},2000)}function a$($,Z,J,Q,Y="⏳",V,X){let z=B3(Z)&&Q!=null?nM(J,Q):y1(Z,J),H=z.length>80?z.slice(0,80)+"…":z,G=x2(Z),W=H?`${Y} \uD83D\uDD27 ${G}: ${H}`:`${Y} \uD83D\uDD27 ${G}`,K=V?`
175
+ `):F$($??{},2000)}function GO($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${u(typeof Z?.tool==="string"&&Z.tool?Z.tool:KW($))}`],V=Z?.input;if(V&&typeof V==="object")if(Y.push(""),Y.push("**input**"),Object.keys(V).length>0)Y.push(F$(V,2000));else Y.push("_provider 未提供结构化 input_");else if(V!=null&&V!=="")Y.push(`**input**: ${u(V)}`);if(Q)Y.push(""),Y.push(Q);if(J!=null)Y.push(""),Y.push("---"),Y.push("**结果**"),Y.push(K1(J,3000));return Y.join(`
176
+ `)}function WO($){return typeof $?.status==="string"?$.status:""}function kW($,Z,J,Q){let Y=[];if($?.status)Y.push(`**状态**: ${u($.status)}`);if($?.prompt)Y.push("","**提示词**",G$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Y.push("",$.prompt?"**实际提示词**":"**提示词**",G$(String($.revisedPrompt)))}if(J)Y.push(""),Y.push(J);if(!Q&&Z!=null&&Z.trim())Y.push(""),Y.push("---"),Y.push("**输出**"),Y.push(u(Z.trim()));return Y.length>0?Y.join(`
177
+ `):F$($??{},2000)}function KO($){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 d7($,Z,J){let Q=[];if($?.tool)Q.push(`**tool**: ${u($.tool)}`);if($?.model)Q.push(`**model**: ${u($.model)}`);if($?.description)Q.push(`**描述**: ${$.description}`);if($?.subagent_type)Q.push(`**类型**: ${u($.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=MQ(Z);Q.push(Y?F$(Y,3000):G$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
178
+ `):F$($??{},2000)}function a$($,Z,J,Q,Y="⏳",V,X){let z=j3(Z)&&Q!=null?zO(J,Q):y1(Z,J),H=z.length>80?z.slice(0,80)+"…":z,G=S2(Z),W=H?`${Y} \uD83D\uDD27 ${G}: ${H}`:`${Y} \uD83D\uDD27 ${G}`,K=V?`
178
179
 
179
- ${V}`:"",j=d7(Z)?zW(J,Q,V):i7(Z)?HW(J,Q,V):Z6(Z)?oM(Z,J,Q,V):n7(Z)?jW(J,Q,V):B3(Z)?OW(J,Q,V):a7(Z)?AW(J,Q,V):qQ(Z)?NW(J,Q,V):j3(Z)?RW(J,Q,V,X):o7(Z)?PW(J,Q,V):s7(Z)?LW(J,Q,V):t7(Z)?qW(J,Q,V):r7(Z)?DW(J,Q,V):FQ(Z)?FW(Z,J,Q,V):e7(Z)?UW(J,Q,V):$6(Z)?u7({prompt:_3(J)||"提交计划"},Q,V):DQ(Z)?u7(J,Q,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
180
+ ${V}`:"",j=i7(Z)?_W(J,Q,V):n7(Z)?LW(J,Q,V):J6(Z)?GO(Z,J,Q,V):a7(Z)?UW(J,Q,V):j3(Z)?SW(J,Q,V):o7(Z)?CW(J,Q,V):DQ(Z)?bW(J,Q,V):_3(Z)?kW(J,Q,V,X):s7(Z)?OW(J,Q,V):t7(Z)?AW(J,Q,V):r7(Z)?NW(J,Q,V):e7(Z)?RW(J,Q,V):UQ(Z)?TW(Z,J,Q,V):$6(Z)?EW(J,Q,V):Z6(Z)?d7({prompt:L3(J)||"提交计划"},Q,V):FQ(Z)?d7(J,Q,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
180
181
  ---
181
182
  **output:**
182
183
  \`\`\`
183
- `+Q.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!1,elements:[{tag:"markdown",content:J0(j)},...j3(Z)&&X?[{tag:"img",img_key:X,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function P3($,Z){let J=Z.length,Q=Z.some((H)=>H.isError),Y=Z.every((H)=>H.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let H=JW(Z[0]);return H?`${V} \uD83D\uDD27 编辑文件: ${H}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,z=Z.map((H)=>{let G=JW(H);return G?`\`${G}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:J0(z.join(`
184
- `))}]}}function JW($){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 L3($,Z){let J=Z.length,Q=Z.some((H)=>H.isError),Y=Z.every((H)=>H.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let H=y1("Read",Z[0]?.input);return H?`${V} \uD83D\uDD27 Read: ${H}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,z=Z.map((H)=>`\`${String(H.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:J0(z.join(`
185
- `))}]}}function NQ($,Z,J,Q){let Y=y1(Z,J),V=x2(Z),X=Y?`\uD83D\uDD10 等审批 · ${V}: ${Y}`:`\uD83D\uDD10 等审批 · ${V}`,z=d7(Z)?zW(J,null):i7(Z)?HW(J,null):n7(Z)?jW(J,null):B3(Z)?OW(J,null):a7(Z)?AW(J,null):qQ(Z)?NW(J,null):j3(Z)?RW(J,null):o7(Z)?PW(J,null):s7(Z)?LW(J,null):t7(Z)?qW(J,null):r7(Z)?DW(J,null):FQ(Z)?FW(Z,J,null):e7(Z)?UW(J,null):$6(Z)?u7({prompt:_3(J)||"提交计划"},null):DQ(Z)?u7(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!0,elements:[{tag:"markdown",content:z},{tag:"column_set",columns:[BQ("✅ 允许","primary",Q,"allow"),BQ("♾️ 始终允许","default",Q,"allow_always"),BQ("❌ 拒绝","danger",Q,"deny")]}]}}function BQ($,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 kM=300,QW="server_tool:";var TW=N(()=>{h0();D8()});import{execFile as rM}from"node:child_process";import{readFileSync as bW,statfsSync as eM,statSync as EW}from"node:fs";import{cpus as $O,homedir as ZO,loadavg as JO,totalmem as QO}from"node:os";import{promisify as YO}from"node:util";function VO(){try{let[$,Z,J]=JO(),Q=$O().length;if(!Q||![$,Z,J].every((Y)=>Number.isFinite(Y)&&Y>=0))throw Error("CPU 核数或负载无效");return{cores:Q,load1:$,load5:Z,load15:J}}catch($){return B(`sysinfo: read CPU failed: ${$}`),null}}function XO(){try{let $=bW("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));if(!X)throw Error(`/proc/meminfo 缺少 ${V}`);return Number(X[1])*1024},J=Z("MemTotal"),Q=Z("MemAvailable");if(J<=0||Q>J)throw Error("/proc/meminfo 内存数据无效");let Y=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 zO($,Z){let J=$.match(/^Mach Virtual Memory Statistics: \(page size of (\d+) bytes\)/m);if(!J)throw Error("vm_stat 缺少 page size");let Q=Number(J[1]);if(!Number.isSafeInteger(Q)||Q<=0||!Number.isSafeInteger(Z)||Z<=0)throw Error("macOS 内存总量或 page size 无效");let Y=(z)=>{let H=$.match(new RegExp(`^${z}:\\s+(\\d+)\\.\\s*$`,"m"));if(!H||!Number.isSafeInteger(Number(H[1])))throw Error(`vm_stat 缺少或无效 ${z}`);return Number(H[1])},V=Y("Anonymous pages")-Y("Pages purgeable"),X=(V+Y("Pages wired down")+Y("Pages occupied by compressor"))*Q;if(V<0||!Number.isSafeInteger(X)||X>Z)throw Error("vm_stat 内存数据超出物理内存范围");return{totalBytes:Z,availBytes:Z-X,usedBytes:X,percent:Math.round(X/Z*100)}}async function HO($=wW){try{return zO(await $("/usr/bin/vm_stat",[]),QO())}catch(Z){return B(`sysinfo: read macOS memory failed: ${Z}`),null}}function GO($){let Z=$.trim().split(/\r?\n/);if(!/^PID\s+Status\s+Label$/.test(Z.shift()?.trim()??""))throw Error("launchctl list 表头无效");let J=[];for(let Q of Z){if(!Q.trim())continue;let Y=Q.trim().match(/^(\d+|-)\s+(-?\d+)\s+(\S+)$/);if(!Y)throw Error(`launchctl list 行无效: ${Q.trim()}`);let[,V,X,z]=Y;if(!RQ.some((W)=>z.startsWith(W)))continue;let H=V==="-"?null:Number(V),G=Number(X);if(H!==null&&(!Number.isSafeInteger(H)||H<=0)||!Number.isSafeInteger(G))throw Error(`launchctl list PID 或退出状态无效: ${z}`);J.push({name:z,pid:H,lastExitStatus:G,active:H!==null?"active":G===0?"inactive":"failed",sub:H!==null?"running":G<0?"signal":"exited",hasStarted:H!==null||G!==0?!0:null,lastActiveAgoSec:null,stateAgoSec:null})}return J.sort((Q,Y)=>Q.name.localeCompare(Y.name))}function WO($){let Z=new Map;for(let J of $.split(`
186
- `)){if(!J.trim())continue;let Q=J.trim().match(/^(\d+)\s+(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/);if(!Q)throw Error(`ps etime 行无效: ${J.trim()}`);let Y=Number(Q[1]),V=Q[2]===void 0?0:Number(Q[2]),X=Q[3]===void 0?0:Number(Q[3]),z=Number(Q[4]),H=Number(Q[5]),G=((V*24+X)*60+z)*60+H;if(!Number.isSafeInteger(Y)||Y<=0||!Number.isSafeInteger(G)||z>=60||H>=60||Q[2]!==void 0&&(Q[3]===void 0||X>=24))throw Error(`ps etime 数值无效: ${J.trim()}`);Z.set(Y,G)}return Z}async function KO($=wW){let Z;try{Z=GO(await $("/bin/launchctl",["list"]))}catch(Q){return B(`sysinfo: launchctl list failed: ${Q}`),{services:[],error:`launchctl 查询失败: ${Q instanceof Error?Q.message:String(Q)}`}}let J=Z.filter((Q)=>Q.pid!==null);if(J.length>0)try{let Q=WO(await $("/bin/ps",["-p",J.map((Y)=>Y.pid).join(","),"-o","pid=,etime="]));for(let Y of J){let V=Q.get(Y.pid);if(V===void 0)Y.error="ps 未返回该进程,运行时长 MISS",B(`sysinfo: ${Y.name}: ${Y.error}`);else Y.lastActiveAgoSec=V,Y.stateAgoSec=V}}catch(Q){B(`sysinfo: read launchd process elapsed failed: ${Q}`);for(let Y of J)Y.error=`运行时长 MISS: ${Q instanceof Error?Q.message:String(Q)}`}return{services:Z.map(({pid:Q,...Y})=>Y),error:null}}function xW($,Z){try{let J=eM(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 BO(){let $=[],Z=xW("/","/");if(Z)$.push(Z);let J=ZO();if(J&&J!=="/"){let Q=!1;try{let Y=EW("/"),V=EW(J);Q=Y.dev===V.dev}catch{}if(!Q){let Y=xW("$HOME",J);if(Y)$.push(Y)}}return $}function jO(){try{let $=bW("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function SW($,Z=2000){try{let{stdout:J}=await kW("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function CW($){return RQ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function _O(){let $=await SW(["list-units","--type=service","--all","--no-legend","--plain",...RQ.map((H)=>`${H}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
187
- `).map((H)=>H.trim()).filter((H)=>H.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let H of Z){let W=H.replace(/^●\s*/,"").split(/\s+/)[0];if(!W)continue;if(!CW(W))continue;J.push(W)}if(J.length===0)return{services:[],error:null};let Q=await SW(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=jO(),V=Q.split(/\n\s*\n/),X=[],z=(H)=>{let G=parseInt(H??"0",10);if(G<=0||Y===null)return null;return Math.max(0,Y-G/1e6)};for(let H of V){let G={};for(let K of H.split(`
188
- `)){let j=K.indexOf("=");if(j<=0)continue;G[K.slice(0,j)]=K.slice(j+1)}let W=G.Id??"";if(!CW(W))continue;X.push({name:W.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:z(G.ActiveEnterTimestampMonotonic),stateAgoSec:z(G.StateChangeTimestampMonotonic),hasStarted:G.ActiveEnterTimestampMonotonic==="0"?!1:null})}return X.sort((H,G)=>H.name.localeCompare(G.name)),{services:X,error:null}}async function vW(){if(process.platform!=="linux"&&process.platform!=="darwin"){let V=process.platform==="win32"?"Windows":process.platform;return{cpu:null,mem:null,disks:[],services:[],servicesError:`${V}: sysinfo 暂未支持`}}let $=VO(),Z=BO(),[J,{services:Q,error:Y}]=await Promise.all([process.platform==="darwin"?HO():XO(),process.platform==="darwin"?KO():_O()]);return{cpu:$,mem:J,disks:Z,services:Q,servicesError:Y}}var kW,RQ,q3="cc-* / codex-*",wW=async($,Z)=>{let{stdout:J}=await kW($,Z,{timeout:2000,maxBuffer:4194304,env:{...process.env,LC_ALL:"C",LANG:"C"}});return J};var TQ=N(()=>{h();kW=YO(rM),RQ=["cc-","codex-"]});function J6($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function PO($){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 LO($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Q=`${J6(J)} ${PO($.percent)}`;if($.kind==="monthly")return Q;if($.unreportedFull)return`${Q}(满窗)`;return`${Q}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?u$($.resetsAt):"MISS"}`}function yW($){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 · ${J6(Y.slice(0,100))}</font>`}let Z=(Y,V)=>{if(!Number.isFinite(Y))return"MISS";return`${V==="USD"?"$":V==="CNY"?"¥":J6(V)} ${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(LO);if(!J.length)J.push("额度 MISS");let Q=$.credits!==void 0?W1($.credits):null;if(Q)J.push(Q);if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function fW($){return{tag:"markdown",text_size:"notation",content:`**${J6($.label)}** ${yW($.usage)}`}}var hW=N(()=>{I4()});function F3($,Z){return Z}function EQ($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:b.footer,content:F3($.title,$.status)}]}}}function IW($){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 qO($){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 D3($){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 MO($){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 OO($){if(!$)return["**负载** MISS","**内存** MISS",`**服务** ${q3} MISS`].join(`
189
- `);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("**负载** MISS");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${IW($.mem.usedBytes)}/${IW($.mem.totalBytes)})`);else Z.push("**内存** MISS");if($.servicesError)Z.push(`**服务** ${q3} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${q3} _无_`);else{Z.push(`**服务** ${q3} (${$.services.length})`);for(let J of $.services){let Q=UO[J.active]??"·",Y=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${D3(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${D3(Y*1000)}前`);else if(J.hasStarted===!1)X.push("从未启动");else X.push("上次活跃 MISS");if(V!=null){let z=J.active==="failed"?"已挂":"已停";X.push(`${z} ${D3(V*1000)}`)}}else if(V!=null)X.push(`已 ${D3(V*1000)}`);if(J.active!=="active"&&J.lastExitStatus!==void 0)X.push(J.lastExitStatus<0?`终止信号 ${-J.lastExitStatus}`:`退出码 ${J.lastExitStatus}`);if(J.error)X.push(J.error);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
190
- `)}function AO($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=DO[J.status]??"·",Y=FO[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${D3(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",z=J.codexAccountName===void 0?"":` · Codex:${h1(U$(J.codexAccountName))}`;return` · ${Q} \`${J.name}\` · ${Y}${V}${X}${z}`}).join(`
191
- `)}function Q6($,Z=b.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:AO($)}]}}function NO($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${wQ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
192
- `)}function Y6($,Z=b.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:NO($)}}function V6($,Z=b.consoleHost){let J=MO($);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:OO($)}]}}function xQ($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(V,X)=>`${X==="USD"?"$":X==="CNY"?"¥":`${X} `}${V.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)}`;let Q=$.windows.length?`额度 ${$.windows.map(RO).join(" · ")}`:"额度 MISS",Y=$.credits!==void 0?W1($.credits):null;return[Q,Y].filter(Boolean).join(" · ")}function RO($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function U3($){let Z=$.accountUsages;return{tag:"collapsible_panel",element_id:b.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(fW):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function gW($,Z){return[Y6($,Z),Q6($),V6($.sysinfo),U3($)]}function X6($){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:gW($)}}}function SQ($){return S2($.sessionName,{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${h1($.currentDisplay??"未选择")}
193
- 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Q)=>(Q.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:b.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)=>TO(Q,$.panelId))}]:[]})]})}function TO($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${U$($.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} 个模型${$.catalogError?` · 刷新 MISS:${$.catalogError}`:""}`,Q=[$.selected?"当前账号":"",J].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${U$($.display)}**
194
- ${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 CQ($){return S2($.sessionName,mW($))}function bQ($){return S2($.sessionName,G6($))}function M3($){return S2($.sessionName,W6($),"green")}function O3($,Z){return{tag:"collapsible_panel",element_id:b.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:U$(Z)}]}}function z6($,Z,J){return S2($,O3(Z,J),Z?"orange":"red")}function S2($,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 mW($){let Z=SO($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${pW($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
195
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?EO($.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 EO($,Z){let{sourceId:J,page:Q,totalPages:Y}=Z,V=(X,z)=>({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:z}}]}]});return[{tag:"markdown",content:`第 ${Q+1} / ${Y} 页`},{tag:"column_set",columns:[...Q>0?[V("上一页",Q-1)]:[],...Q+1<Y?[V("下一页",Q+1)]:[]]}]}function H6($,Z="cancelled"){return S2($,{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function kQ($,Z,J){return S2($,{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
196
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function A3($,Z,J){return{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
197
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function G6($){return{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${kO($.model)}`,`当前: ${pW($.currentModel,$.currentEffort)}`].join(`
198
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>CO($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function W6($){return{tag:"collapsible_panel",element_id:b.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",h1(cW($.model,$.effort,$.provider)),U$($.scope)].join(`
199
- `)}]}}function xO($,Z,J,Q=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${U$($.displayName)}** · 未配置
200
- ${U$($.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?`**${U$($.displayName)}**`:`**${h1($.model)}**`,V=[$.isDefault?`${wQ($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),X=$.description?`
201
- `+U$(wO($.description,110)):"",z=(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:[Y,$.displayName&&$.displayName!==$.model?h1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
202
- `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[z("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:bO($,Z)}]}],...Q&&J!=="add"?[$.origin==="custom"?z("model_custom_remove","删"):z("model_remove","隐")]:[]]}]}]}function SO($,Z,J,Q=!1){let Y=[{title:"Codex",models:$.filter((z)=>(z.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((z)=>z.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((z)=>z.provider==="dsh")}].filter((z)=>z.models.length>0),V=(z)=>z.flatMap((H,G)=>[...G?[{tag:"hr"}]:[],...xO(H,Z,J,Q)]);if(Y.length<=1)return V($);let X=[];for(let z of Y)X.push({tag:"markdown",content:`**${z.title}**`}),X.push(...V(z.models));return X}function CO($,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"?"模型默认":U$(Z.effort)}**`,X,Z.description?U$(Z.description):""].filter(Boolean).join(`
203
- `)}]},{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 bO($,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 kO($){return $.displayName&&$.displayName!==$.model?`${U$($.displayName)} (${h1($.model)})`:h1($.model)}function pW($,Z){return h1(cW($,Z))}function cW($,Z,J){let Q=J&&J!=="codex"?`${wQ(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function wQ($){return i0($??"codex")}function wO($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function U$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function h1($){return"`"+$.replace(/`/g,"\\`")+"`"}function C2($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${E0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${qO($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var DO,FO,UO;var lW=N(()=>{_0();TQ();h0();I4();hW();I4();DO={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},FO={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},UO={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function vQ($){let Z=fO($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:vO($.notice)},body:{elements:[...$.notice?[yO($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(hO)]}}}function vO($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function yO($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
184
+ `+Q.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!1,elements:[{tag:"markdown",content:Q0(j)},..._3(Z)&&X?[{tag:"img",img_key:X,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function P3($,Z){let J=Z.length,Q=Z.some((H)=>H.isError),Y=Z.every((H)=>H.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let H=GW(Z[0]);return H?`${V} \uD83D\uDD27 编辑文件: ${H}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,z=Z.map((H)=>{let G=GW(H);return G?`\`${G}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:Q0(z.join(`
185
+ `))}]}}function GW($){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 q3($,Z){let J=Z.length,Q=Z.some((H)=>H.isError),Y=Z.every((H)=>H.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let H=y1("Read",Z[0]?.input);return H?`${V} \uD83D\uDD27 Read: ${H}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,z=Z.map((H)=>`\`${String(H.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:Q0(z.join(`
186
+ `))}]}}function RQ($,Z,J,Q){let Y=y1(Z,J),V=S2(Z),X=Y?`\uD83D\uDD10 等审批 · ${V}: ${Y}`:`\uD83D\uDD10 等审批 · ${V}`,z=i7(Z)?_W(J,null):n7(Z)?LW(J,null):a7(Z)?UW(J,null):j3(Z)?SW(J,null):o7(Z)?CW(J,null):DQ(Z)?bW(J,null):_3(Z)?kW(J,null):s7(Z)?OW(J,null):t7(Z)?AW(J,null):r7(Z)?NW(J,null):e7(Z)?RW(J,null):UQ(Z)?TW(Z,J,null):$6(Z)?EW(J,null):Z6(Z)?d7({prompt:L3(J)||"提交计划"},null):FQ(Z)?d7(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!0,elements:[{tag:"markdown",content:z},{tag:"column_set",columns:[jQ("✅ 允许","primary",Q,"allow"),jQ("♾️ 始终允许","default",Q,"allow_always"),jQ("❌ 拒绝","danger",Q,"deny")]}]}}function jQ($,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 iM=300,WW="server_tool:";var wW=R(()=>{h0();F8()});import{execFile as BO}from"node:child_process";import{readFileSync as IW,statfsSync as jO,statSync as vW}from"node:fs";import{cpus as _O,homedir as LO,loadavg as PO,totalmem as qO}from"node:os";import{promisify as DO}from"node:util";function FO(){try{let[$,Z,J]=PO(),Q=_O().length;if(!Q||![$,Z,J].every((Y)=>Number.isFinite(Y)&&Y>=0))throw Error("CPU 核数或负载无效");return{cores:Q,load1:$,load5:Z,load15:J}}catch($){return B(`sysinfo: read CPU failed: ${$}`),null}}function UO(){try{let $=IW("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));if(!X)throw Error(`/proc/meminfo 缺少 ${V}`);return Number(X[1])*1024},J=Z("MemTotal"),Q=Z("MemAvailable");if(J<=0||Q>J)throw Error("/proc/meminfo 内存数据无效");let Y=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 MO($,Z){let J=$.match(/^Mach Virtual Memory Statistics: \(page size of (\d+) bytes\)/m);if(!J)throw Error("vm_stat 缺少 page size");let Q=Number(J[1]);if(!Number.isSafeInteger(Q)||Q<=0||!Number.isSafeInteger(Z)||Z<=0)throw Error("macOS 内存总量或 page size 无效");let Y=(z)=>{let H=$.match(new RegExp(`^${z}:\\s+(\\d+)\\.\\s*$`,"m"));if(!H||!Number.isSafeInteger(Number(H[1])))throw Error(`vm_stat 缺少或无效 ${z}`);return Number(H[1])},V=Y("Anonymous pages")-Y("Pages purgeable"),X=(V+Y("Pages wired down")+Y("Pages occupied by compressor"))*Q;if(V<0||!Number.isSafeInteger(X)||X>Z)throw Error("vm_stat 内存数据超出物理内存范围");return{totalBytes:Z,availBytes:Z-X,usedBytes:X,percent:Math.round(X/Z*100)}}async function OO($=mW){try{return MO(await $("/usr/bin/vm_stat",[]),qO())}catch(Z){return B(`sysinfo: read macOS memory failed: ${Z}`),null}}function AO($){let Z=$.trim().split(/\r?\n/);if(!/^PID\s+Status\s+Label$/.test(Z.shift()?.trim()??""))throw Error("launchctl list 表头无效");let J=[];for(let Q of Z){if(!Q.trim())continue;let Y=Q.trim().match(/^(\d+|-)\s+(-?\d+)\s+(\S+)$/);if(!Y)throw Error(`launchctl list 行无效: ${Q.trim()}`);let[,V,X,z]=Y;if(!TQ.some((W)=>z.startsWith(W)))continue;let H=V==="-"?null:Number(V),G=Number(X);if(H!==null&&(!Number.isSafeInteger(H)||H<=0)||!Number.isSafeInteger(G))throw Error(`launchctl list PID 或退出状态无效: ${z}`);J.push({name:z,pid:H,lastExitStatus:G,active:H!==null?"active":G===0?"inactive":"failed",sub:H!==null?"running":G<0?"signal":"exited",hasStarted:H!==null||G!==0?!0:null,lastActiveAgoSec:null,stateAgoSec:null})}return J.sort((Q,Y)=>Q.name.localeCompare(Y.name))}function NO($){let Z=new Map;for(let J of $.split(`
187
+ `)){if(!J.trim())continue;let Q=J.trim().match(/^(\d+)\s+(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/);if(!Q)throw Error(`ps etime 行无效: ${J.trim()}`);let Y=Number(Q[1]),V=Q[2]===void 0?0:Number(Q[2]),X=Q[3]===void 0?0:Number(Q[3]),z=Number(Q[4]),H=Number(Q[5]),G=((V*24+X)*60+z)*60+H;if(!Number.isSafeInteger(Y)||Y<=0||!Number.isSafeInteger(G)||z>=60||H>=60||Q[2]!==void 0&&(Q[3]===void 0||X>=24))throw Error(`ps etime 数值无效: ${J.trim()}`);Z.set(Y,G)}return Z}async function RO($=mW){let Z;try{Z=AO(await $("/bin/launchctl",["list"]))}catch(Q){return B(`sysinfo: launchctl list failed: ${Q}`),{services:[],error:`launchctl 查询失败: ${Q instanceof Error?Q.message:String(Q)}`}}let J=Z.filter((Q)=>Q.pid!==null);if(J.length>0)try{let Q=NO(await $("/bin/ps",["-p",J.map((Y)=>Y.pid).join(","),"-o","pid=,etime="]));for(let Y of J){let V=Q.get(Y.pid);if(V===void 0)Y.error="ps 未返回该进程,运行时长 MISS",B(`sysinfo: ${Y.name}: ${Y.error}`);else Y.lastActiveAgoSec=V,Y.stateAgoSec=V}}catch(Q){B(`sysinfo: read launchd process elapsed failed: ${Q}`);for(let Y of J)Y.error=`运行时长 MISS: ${Q instanceof Error?Q.message:String(Q)}`}return{services:Z.map(({pid:Q,...Y})=>Y),error:null}}function yW($,Z){try{let J=jO(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 TO(){let $=[],Z=yW("/","/");if(Z)$.push(Z);let J=LO();if(J&&J!=="/"){let Q=!1;try{let Y=vW("/"),V=vW(J);Q=Y.dev===V.dev}catch{}if(!Q){let Y=yW("$HOME",J);if(Y)$.push(Y)}}return $}function EO(){try{let $=IW("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function fW($,Z=2000){try{let{stdout:J}=await gW("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function hW($){return TQ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function xO(){let $=await fW(["list-units","--type=service","--all","--no-legend","--plain",...TQ.map((H)=>`${H}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
188
+ `).map((H)=>H.trim()).filter((H)=>H.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let H of Z){let W=H.replace(/^●\s*/,"").split(/\s+/)[0];if(!W)continue;if(!hW(W))continue;J.push(W)}if(J.length===0)return{services:[],error:null};let Q=await fW(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=EO(),V=Q.split(/\n\s*\n/),X=[],z=(H)=>{let G=parseInt(H??"0",10);if(G<=0||Y===null)return null;return Math.max(0,Y-G/1e6)};for(let H of V){let G={};for(let K of H.split(`
189
+ `)){let j=K.indexOf("=");if(j<=0)continue;G[K.slice(0,j)]=K.slice(j+1)}let W=G.Id??"";if(!hW(W))continue;X.push({name:W.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:z(G.ActiveEnterTimestampMonotonic),stateAgoSec:z(G.StateChangeTimestampMonotonic),hasStarted:G.ActiveEnterTimestampMonotonic==="0"?!1:null})}return X.sort((H,G)=>H.name.localeCompare(G.name)),{services:X,error:null}}async function pW(){if(process.platform!=="linux"&&process.platform!=="darwin"){let V=process.platform==="win32"?"Windows":process.platform;return{cpu:null,mem:null,disks:[],services:[],servicesError:`${V}: sysinfo 暂未支持`}}let $=FO(),Z=TO(),[J,{services:Q,error:Y}]=await Promise.all([process.platform==="darwin"?OO():UO(),process.platform==="darwin"?RO():xO()]);return{cpu:$,mem:J,disks:Z,services:Q,servicesError:Y}}var gW,TQ,D3="cc-* / codex-*",mW=async($,Z)=>{let{stdout:J}=await gW($,Z,{timeout:2000,maxBuffer:4194304,env:{...process.env,LC_ALL:"C",LANG:"C"}});return J};var EQ=R(()=>{h();gW=DO(BO),TQ=["cc-","codex-"]});function Q6($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function SO($){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 CO($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Q=`${Q6(J)} ${SO($.percent)}`;if($.kind==="monthly")return Q;if($.unreportedFull)return`${Q}(满窗)`;return`${Q}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?u$($.resetsAt):"MISS"}`}function cW($){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 · ${Q6(Y.slice(0,100))}</font>`}let Z=(Y,V)=>{if(!Number.isFinite(Y))return"MISS";return`${V==="USD"?"$":V==="CNY"?"¥":Q6(V)} ${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(CO);if(!J.length)J.push("额度 MISS");let Q=$.credits!==void 0?W1($.credits):null;if(Q)J.push(Q);if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function lW($){return{tag:"markdown",text_size:"notation",content:`**${Q6($.label)}** ${cW($.usage)}`}}var uW=R(()=>{I4()});function U3($,Z){return Z}function xQ($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:C.footer,content:U3($.title,$.status)}]}}}function dW($){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 bO($){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 F3($){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 yO($){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 fO($){if(!$)return["**负载** MISS","**内存** MISS",`**服务** ${D3} MISS`].join(`
190
+ `);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("**负载** MISS");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${dW($.mem.usedBytes)}/${dW($.mem.totalBytes)})`);else Z.push("**内存** MISS");if($.servicesError)Z.push(`**服务** ${D3} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${D3} _无_`);else{Z.push(`**服务** ${D3} (${$.services.length})`);for(let J of $.services){let Q=vO[J.active]??"·",Y=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${F3(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${F3(Y*1000)}前`);else if(J.hasStarted===!1)X.push("从未启动");else X.push("上次活跃 MISS");if(V!=null){let z=J.active==="failed"?"已挂":"已停";X.push(`${z} ${F3(V*1000)}`)}}else if(V!=null)X.push(`已 ${F3(V*1000)}`);if(J.active!=="active"&&J.lastExitStatus!==void 0)X.push(J.lastExitStatus<0?`终止信号 ${-J.lastExitStatus}`:`退出码 ${J.lastExitStatus}`);if(J.error)X.push(J.error);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
191
+ `)}function hO($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=kO[J.status]??"·",Y=wO[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${F3(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",z=J.codexAccountName===void 0?"":` · Codex:${h1(U$(J.codexAccountName))}`;return` · ${Q} \`${J.name}\` · ${Y}${V}${X}${z}`}).join(`
192
+ `)}function Y6($,Z=C.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:hO($)}]}}function IO($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${vQ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
193
+ `)}function V6($,Z=C.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:IO($)}}function X6($,Z=C.consoleHost){let J=yO($);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:fO($)}]}}function SQ($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(V,X)=>`${X==="USD"?"$":X==="CNY"?"¥":`${X} `}${V.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)}`;let Q=$.windows.length?`额度 ${$.windows.map(gO).join(" · ")}`:"额度 MISS",Y=$.credits!==void 0?W1($.credits):null;return[Q,Y].filter(Boolean).join(" · ")}function gO($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function M3($){let Z=$.accountUsages;return{tag:"collapsible_panel",element_id:C.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(lW):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function iW($,Z){return[V6($,Z),Y6($),X6($.sysinfo),M3($)]}function z6($){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:iW($)}}}function CQ($){return C2($.sessionName,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${h1($.currentDisplay??"未选择")}
194
+ 选账号进入模型选择。`},...["claude","codex","dsh"].flatMap((Z)=>{let J=$.providers.filter((Q)=>(Q.provider??"codex")===Z);return J.length?[{tag:"collapsible_panel",element_id:C.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)=>mO(Q,$.panelId))}]:[]})]})}function mO($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${U$($.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} 个模型${$.catalogError?` · 刷新 MISS:${$.catalogError}`:""}`,Q=[$.selected?"当前账号":"",J].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${U$($.display)}**
195
+ ${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 bQ($){return C2($.sessionName,nW($))}function kQ($){return C2($.sessionName,W6($))}function O3($){return C2($.sessionName,K6($),"green")}function A3($,Z){return{tag:"collapsible_panel",element_id:C.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:U$(Z)}]}}function H6($,Z,J){return C2($,A3(Z,J),Z?"orange":"red")}function C2($,Z,J="turquoise"){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83E\uDD16 model · ${$}`},template:J},body:{elements:[Z]}}}function nW($){let Z=lO($.models,$.panelId,$.mode,$.editable);return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:$.mode==="add"?"显示模型":"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${aW($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
196
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?pO($.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 pO($,Z){let{sourceId:J,page:Q,totalPages:Y}=Z,V=(X,z)=>({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:z}}]}]});return[{tag:"markdown",content:`第 ${Q+1} / ${Y} 页`},{tag:"column_set",columns:[...Q>0?[V("上一页",Q-1)]:[],...Q+1<Y?[V("下一页",Q+1)]:[]]}]}function G6($,Z="cancelled"){return C2($,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function wQ($,Z,J){return C2($,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**`,"补录后可选择 effort 并使用;模型是否接受该档位由实际请求确认。","_裸词命令(hi/stop/model 等)不受影响_"].join(`
197
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function N3($,Z,J){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
198
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function W6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${iO($.model)}`,`当前: ${aW($.currentModel,$.currentEffort)}`].join(`
199
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>uO($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function K6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",h1(oW($.model,$.effort,$.provider)),U$($.scope)].join(`
200
+ `)}]}}function cO($,Z,J,Q=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${U$($.displayName)}** · 未配置
201
+ ${U$($.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?`**${U$($.displayName)}**`:`**${h1($.model)}**`,V=[$.isDefault?`${vQ($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),X=$.description?`
202
+ `+U$(nO($.description,110)):"",z=(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:[Y,$.displayName&&$.displayName!==$.model?h1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
203
+ `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[z("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:dO($,Z)}]}],...Q&&J!=="add"?[$.origin==="custom"?z("model_custom_remove","删"):z("model_remove","隐")]:[]]}]}]}function lO($,Z,J,Q=!1){let Y=[{title:"Codex",models:$.filter((z)=>(z.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((z)=>z.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((z)=>z.provider==="dsh")}].filter((z)=>z.models.length>0),V=(z)=>z.flatMap((H,G)=>[...G?[{tag:"hr"}]:[],...cO(H,Z,J,Q)]);if(Y.length<=1)return V($);let X=[];for(let z of Y)X.push({tag:"markdown",content:`**${z.title}**`}),X.push(...V(z.models));return X}function uO($,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"?"模型默认":U$(Z.effort)}**`,X,Z.description?U$(Z.description):""].filter(Boolean).join(`
204
+ `)}]},{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 dO($,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 iO($){return $.displayName&&$.displayName!==$.model?`${U$($.displayName)} (${h1($.model)})`:h1($.model)}function aW($,Z){return h1(oW($,Z))}function oW($,Z,J){let Q=J&&J!=="codex"?`${vQ(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function vQ($){return i0($??"codex")}function nO($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function U$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function h1($){return"`"+$.replace(/`/g,"\\`")+"`"}function b2($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${E0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${bO($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var kO,wO,vO;var sW=R(()=>{_0();EQ();h0();I4();uW();I4();kO={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},wO={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},vO={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function yQ($){let Z=sO($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:aO($.notice)},body:{elements:[...$.notice?[oO($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(tO)]}}}function aO($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function oO($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
204
205
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
205
- `)}}function fO($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${K6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function hO($){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:`**${K6($.slug)}**
206
+ `)}}function sO($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${B6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function tO($){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:`**${B6($.slug)}**
206
207
  ${Z} · ${J}
207
- ${K6($.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 N3($){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,K6($.branch),...$.body?[$.body]:[]].join(`
208
- `)}]}}}function K6($){return"`"+$.replace(/`/g,"\\`")+"`"}function fQ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
208
+ ${B6($.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 R3($){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,B6($.branch),...$.body?[$.body]:[]].join(`
209
+ `)}]}}}function B6($){return"`"+$.replace(/`/g,"\\`")+"`"}function hQ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
209
210
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
210
- 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:IO($.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:`**${mQ(X.ts)}**
211
- ${I1(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 hQ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
212
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${mQ(J.ts)}**
213
- ${I1(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 IQ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
211
+ 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:rO($.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:`**${pQ(X.ts)}**
212
+ ${I1(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 IQ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
213
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${pQ(J.ts)}**
214
+ ${I1(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 gQ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
214
215
  …(截断)`:J.body;return`${J.path} (${J.tool})
215
216
  ${Q}`}).join(`
216
217
 
217
- `);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 g1($){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?"✅":"❌"} ${yQ($.message)}`}]}}}function gQ($){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?` · 状态 ${I1($.sourceStatus)}`:"",X=$.bindingState==="changed"?["**当前群**",`新会话 ${I1(B6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
218
+ `);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 g1($){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?"✅":"❌"} ${fQ($.message)}`}]}}}function mQ($){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?` · 状态 ${I1($.sourceStatus)}`:"",X=$.bindingState==="changed"?["**当前群**",`新会话 ${I1(j6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
218
219
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
219
- `):$.bindingState==="unchanged"?[`${yQ($.message)}`,"",`本群原绑定 ${I1(B6($.previousSessionId))};源会话未修改。`].join(`
220
- `):[`${yQ($.message)}`,"",`后端返回会话 ${I1(B6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
221
- `);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}**`,`**${mQ($.selectedTs)}**${V}`,I1(Y),`源会话 ${I1(B6($.sourceSessionId))}`].join(`
222
- `)},{tag:"markdown",content:X}]}}}function mQ($){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 I1($){return"`"+uW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function B6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function yQ($){return uW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function uW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function IO($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
220
+ `):$.bindingState==="unchanged"?[`${fQ($.message)}`,"",`本群原绑定 ${I1(j6($.previousSessionId))};源会话未修改。`].join(`
221
+ `):[`${fQ($.message)}`,"",`后端返回会话 ${I1(j6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
222
+ `);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}**`,`**${pQ($.selectedTs)}**${V}`,I1(Y),`源会话 ${I1(j6($.sourceSessionId))}`].join(`
223
+ `)},{tag:"markdown",content:X}]}}}function pQ($){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 I1($){return"`"+tW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function j6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function fQ($){return tW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function tW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function rO($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
223
224
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
224
- `)}function dW($){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(`
225
+ `)}function rW($){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(`
225
226
  ---
226
- `);return""}function pQ($,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:dW(Z)}]}function lQ($){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?[pO($.notice)]:[],{tag:"markdown",element_id:b.tasklistPanel,content:gO($)},mO($)]}}}function gO($){let Z=[`项目:${cQ($.projectName)}`,`清单:${cQ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
227
- `);if(Z.push("","已启用"),Z.push(`GUID:${cQ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
228
- `)}function mO($){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 pO($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
229
- `).map((J)=>`<font color='${Z}'>${cO(J)||" "}</font>`).join(`
230
- `)}}function cQ($){return"`"+$.replace(/`/g,"\\`")+"`"}function cO($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var iW=N(()=>{h0()});import{createHash as lO}from"node:crypto";function dQ($){let Z=[{tag:"markdown",element_id:b.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
227
+ `);return""}function cQ($,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:rW(Z)}]}function uQ($){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?[ZA($.notice)]:[],{tag:"markdown",element_id:C.tasklistPanel,content:eO($)},$A($)]}}}function eO($){let Z=[`项目:${lQ($.projectName)}`,`清单:${lQ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
228
+ `);if(Z.push("","已启用"),Z.push(`GUID:${lQ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
229
+ `)}function $A($){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 ZA($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
230
+ `).map((J)=>`<font color='${Z}'>${JA(J)||" "}</font>`).join(`
231
+ `)}}function lQ($){return"`"+$.replace(/`/g,"\\`")+"`"}function JA($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var eW=R(()=>{h0()});import{createHash as QA}from"node:crypto";function iQ($){let Z=[{tag:"markdown",element_id:C.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
231
232
  `)}];if($.failures.length)Z.push({tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`MISS · ${$.failures.length} 个账号`}},expanded:!1,elements:[{tag:"markdown",content:$.failures.map((J)=>`- **${o$(J.display)}**:${o$(J.reason)}`).join(`
232
- `)}]});return Z.push(...$.catalog.map(uO),dO($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function iQ($){let Z=$.owner?.kind==="project";return{tag:"collapsible_panel",element_id:j6($.runId),header:{title:{tag:"plain_text",content:_6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${o$($.description??"说明 MISS")}**`,...Z?[`项目 ${B1($.owner.name)} · ${B1($.runId)}`]:[],oW($).content,`**任务说明**
233
- ${J0(Y3($.prompt))}`,...$.workers.map((J)=>aW(J,nW,Z).content),...Z&&$.status==="needs_input"?["通过调用端的 `answer` 命令回答,普通群消息仍发送给主会话。"]:[]].join(`
233
+ `)}]});return Z.push(...$.catalog.map(YA),VA($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function nQ($){let Z=$.owner?.kind==="project";return{tag:"collapsible_panel",element_id:_6($.runId),header:{title:{tag:"plain_text",content:L6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${o$($.description??"说明 MISS")}**`,...Z?[`项目 ${B1($.owner.name)} · ${B1($.runId)}`]:[],JK($).content,`**任务说明**
234
+ ${Q0(V3($.prompt))}`,...$.workers.map((J)=>ZK(J,$K,Z).content)].join(`
234
235
 
235
- `)},...Z&&!sW($.status)?[{tag:"button",text:{tag:"plain_text",content:"停止本次任务"},type:"danger",behaviors:[{type:"callback",value:{kind:"agent_project_cancel",run_id:$.runId}}]}]:[]]}}function j6($){return`ar_${lO("sha256").update($).digest("hex").slice(0,16)}`}function nQ($){if($.length===1)return $[0].summary;let Z=$.filter((z)=>z.terminal).length,J=$.filter((z)=>z.status==="failed").length,Q=$.filter((z)=>z.status==="needs_input"||z.status==="paused").length,Y=new Set($.map((z)=>z.kind??"delegated")),V=yG.filter((z)=>Y.has(z));return`${V.length===1?`${fG(V[0])} ${T2(V[0])}`:`\uD83E\uDDE9 运行任务 · ${V.map((z)=>`${T2(z)} ${$.filter((H)=>(H.kind??"delegated")===z).length}`).join(" · ")}`} · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Q?` · 待处理 ${Q}`:""}`}function aW($,Z=nW,J=!1){let Q=iO($),Y=[`模型 ${B1($.model)} · 推理 ${B1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${E0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",o$($.queuedReason));if($.pendingInput){Y.push("",J?"**等待调用方回答**":"**等待主 Agent 回答**");for(let V of $.pendingInput.questions)if(Y.push(`- ${o$(V.question)}`),V.options.length)Y.push(` 选项:${V.options.map((X)=>B1(X.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",J0($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",J0(k7($.output,Z)));if(!$.output&&!$.error&&!$.pendingInput)Y.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Y.push("","**最近动作**");for(let V of $.steps.slice(-3)){let X=V.tool==="tool error"?"❌":V.phase==="completed"?"✓":V.phase==="started"?"→":"·",z=V.tool==="tool error"?"工具执行失败":V.tool==="tool result"?"工具执行完成":V.tool;Y.push(`- ${X} ${B1(z)} ${o$(rW(V.detail,180))}`)}}return{tag:"markdown",content:[`**${Q} · ${o$($.identityName)}**`,...Y].join(`
236
- `)}}function oW($){let Z=$.workers.filter((W)=>W.status==="completed").length,J=$.workers.filter((W)=>W.status==="failed").length,Q=$.workers.filter((W)=>W.status==="needs_input").length,Y=$.workers.filter((W)=>W.status==="running").length,V=$.workers.filter((W)=>W.status==="queued").length,X=$.workers.filter((W)=>W.status==="cancelled").length,z=[Y?`执行中 ${Y}`:"",V?`排队 ${V}`:"",Q?`待答 ${Q}`:"",J?`失败 ${J}`:"",X?`已取消 ${X}`:""].filter(Boolean),H=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${tW($)}** · 完成 ${Z}/${$.workers.length}`,...z.length?[z.join(" · ")]:[],...H!=null&&Number.isFinite(H)?[`⏱ 用时 ${E0(H/1000)}`]:[],...$.error?[o$($.error)]:[]].join(`
237
- `)}}function _6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${tW($)} · ${rW($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function uO($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${o$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${B1($.id)}
236
+ `)},...Z&&!QK($.status)?[{tag:"button",text:{tag:"plain_text",content:"停止本次任务"},type:"danger",behaviors:[{type:"callback",value:{kind:"agent_project_cancel",run_id:$.runId}}]}]:[]]}}function _6($){return`ar_${QA("sha256").update($).digest("hex").slice(0,16)}`}function aQ($){if($.length===1)return $[0].summary;let Z=$.filter((z)=>z.terminal).length,J=$.filter((z)=>z.status==="failed").length,Q=$.filter((z)=>z.status==="needs_input"||z.status==="paused").length,Y=new Set($.map((z)=>z.kind??"delegated")),V=cG.filter((z)=>Y.has(z));return`${V.length===1?`${lG(V[0])} ${E2(V[0])}`:`\uD83E\uDDE9 运行任务 · ${V.map((z)=>`${E2(z)} ${$.filter((H)=>(H.kind??"delegated")===z).length}`).join(" · ")}`} · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Q?` · 待处理 ${Q}`:""}`}function ZK($,Z=$K,J=!1){let Q=XA($),Y=[`模型 ${B1($.model)} · 推理 ${B1($.effort)}`];if($.durationMs!=null)Y.push(`用时 ${E0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Y.push("",o$($.queuedReason));if($.pendingInput){Y.push("",J?"**项目任务不支持交互提问**":"**等待主 Agent 回答**");for(let V of $.pendingInput.questions)if(Y.push(`- ${o$(V.question)}`),V.options.length)Y.push(` 选项:${V.options.map((X)=>B1(X.label)).join(" / ")}`)}if($.error)Y.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",Q0($.error));if($.output)Y.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",Q0(w7($.output,Z)));if(!$.output&&!$.error&&!$.pendingInput)Y.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Y.push("","**最近动作**");for(let V of $.steps.slice(-3)){let X=V.tool==="tool error"?"❌":V.phase==="completed"?"✓":V.phase==="started"?"→":"·",z=V.tool==="tool error"?"工具执行失败":V.tool==="tool result"?"工具执行完成":V.tool;Y.push(`- ${X} ${B1(z)} ${o$(VK(V.detail,180))}`)}}return{tag:"markdown",content:[`**${Q} · ${o$($.identityName)}**`,...Y].join(`
237
+ `)}}function JK($){let Z=$.workers.filter((W)=>W.status==="completed").length,J=$.workers.filter((W)=>W.status==="failed").length,Q=$.workers.filter((W)=>W.status==="needs_input").length,Y=$.workers.filter((W)=>W.status==="running").length,V=$.workers.filter((W)=>W.status==="queued").length,X=$.workers.filter((W)=>W.status==="cancelled").length,z=[Y?`执行中 ${Y}`:"",V?`排队 ${V}`:"",Q?`待答 ${Q}`:"",J?`失败 ${J}`:"",X?`已取消 ${X}`:""].filter(Boolean),H=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${YK($)}** · 完成 ${Z}/${$.workers.length}`,...z.length?[z.join(" · ")]:[],...H!=null&&Number.isFinite(H)?[`⏱ 用时 ${E0(H/1000)}`]:[],...$.error?[o$($.error)]:[]].join(`
238
+ `)}}function L6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${YK($)} · ${VK($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function YA($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${o$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${B1($.id)}
238
239
  ${B1($.model)} · 默认 ${B1($.defaultEffort??"MISS")} · ${o$(J)}`].join(`
239
- `)}}function dO($){return{tag:"column_set",columns:[uQ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),uQ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),uQ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function uQ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function iO($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function sW($){return $==="completed"||$==="failed"||$==="cancelled"}function tW($){let Z=T2($.owner?.kind==="project"?"project":"delegated");switch($.status){case"completed":return`✅ ${Z}完成`;case"failed":return`❌ ${Z}失败`;case"cancelled":return`\uD83D\uDED1 ${Z}已取消`;case"needs_input":return`❓ ${Z}等待${$.owner?.kind==="project"?"调用方":"主 Agent "}回复`;case"queued":return`⏳ ${Z}等待执行`;case"running":return $.workers.length>0&&$.workers.every((J)=>sW(J.status))?`⏳ ${Z}正在收尾`:`⏳ ${Z}正在执行`}}function B1($){return"`"+$.replace(/`/g,"\\`")+"`"}function o$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function rW($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var nW=8000;var eW=N(()=>{h0();mJ()});function k2($){return nO.has($)?$:null}function P6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function d4($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function b2($){return String($?.subject??$?.content??"").trim()}function aQ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function JK($){return`subj:${$}`}function $K($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function tO($){let Z=b2($);if(!Z)return null;return{id:d4($)||JK(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:aQ($)??"pending"}}function oQ($,Z,J,Q){if(Z==="TaskList"){let Y=P6(Q),V=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(V===null)return $;let X=[];for(let z of V){let H=tO(z);if(H)X.push(H)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let G=P6(Q),W=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,K=$;return Y.forEach((j,_)=>{let D=b2(j);if(!D)return;let L=W?.[_],P=L&&d4(L)||$K(Q??"");K=ZK(K,P,D,j)}),K}let V=P6(Q),X=V?.task??V,z=d4(X)||$K(Q??""),H=b2(X)||b2(J);if(!H)return $;return ZK($,z,H,J)}if(Z==="TaskUpdate"){let Y=d4(J);if(!Y)return $;let V=aQ(J);if(V==="deleted")return $.filter((z)=>z.id!==Y);let X=b2(J);if($.some((z)=>z.id===Y))return $.map((z)=>z.id===Y?{...z,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:z);return $}if(Z==="TaskGet"){let Y=P6(Q),V=Y?.task??Y,X=d4(V)||d4(J);if(!X)return $;let z=$.find((W)=>W.id===X),H=b2(V)||z?.subject||b2(J);if(!H)return $;let G={id:X,subject:H,description:typeof V?.description==="string"?V.description:z?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:z?.activeForm,status:aQ(V)??z?.status??"pending"};return z?$.map((W)=>W.id===X?G:W):[...$,G]}return $}function ZK($,Z,J,Q){let Y=Z||JK(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 sQ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let X=oO[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 QK($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let z=parseInt(X,10);return Number.isNaN(z)?Number.MAX_SAFE_INTEGER:z},V=[...J].sort((X,z)=>{let H=Y(X.id)-Y(z.id);return H!==0?H:X.id.localeCompare(z.id)});for(let X of V.slice(0,12)){let z=sO[X.status],H=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${z} ${H||"(空)"}`)}if(V.length>12)Q.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
240
- `)}function m1($,Z,J,Q){let Y=aO[J.name],V=sQ(Z),X=`${J.status} \uD83D\uDD27 ${Y}: ${V}`;return{tag:"collapsible_panel",element_id:b.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:QK(Z,Q)}]}}function w2($){return{tag:"collapsible_panel",element_id:b.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${sQ($)}`}},expanded:!0,elements:[{tag:"markdown",content:QK($)}]}}var nO,aO,oO,sO;var YK=N(()=>{h0();nO=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);aO={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},oO={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},sO={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var M$=N(()=>{h0();h7();ZW();TW();lW();iW();eW();YK();sJ()});import{createHash as rO}from"node:crypto";class T3{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(VK($))}async update($,Z=!1,J=!1){await this.updateRow(VK($),Z,!1,J)}syncBackground($,Z,J){return R$($,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,z=Q.get(X);if(z?.task===V&&!z.pendingSettings)continue;let H=z&&D$(z.task)&&!D$(V),G=(z?.version??0)+(H?1:0),W=`background:${Z}:${X}:${G}`,K={key:W,chatId:$,elementId:V3.panel(W),element:oJ({...V,id:W}),summary:y7(V),kind:z3(V),status:V.status,terminal:D$(V)};try{if(!z||H)await this.addRow(K);else{let j=!z.pendingSettings&&$A(z.task,V);if(!await this.updateRow(K,K.terminal,!0,j))continue}Q.set(X,{task:V,version:G})}catch(j){if(this.byTask.get(W)?.rows.get(W)===K)Q.set(X,{task:V,version:G,pendingSettings:!0});Y.push(j)}}if(Y.length)throw AggregateError(Y,Y.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return R$($.chatId,async()=>{if(this.byTask.get($.key)){await this.updateRow($,$.terminal,!0);return}let J=$.dedicated?void 0:this.tails.get($.chatId);if(J){if(await this.deps.getChatTailMessageId($.chatId)===J.messageId&&this.deps.getElementCount(J.cardId)<eO){let Y=await this.deps.addElementResult(J.cardId,$.element);if(Y.landed){this.attach(J,$),await this.settings(J);return}if(!tQ(Y))throw R3("agent card append",Y)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1,Q=!1){return R$($.chatId,async()=>{let Y=this.byTask.get($.key);if(!Y)return!0;if(Y.settled.has($.key)&&!J){if(Z)await this.settings(Y);return!0}if(Y.settled.size===Y.rows.size)Y.settingsJson=void 0;let V=[],X=await this.deps.replaceElementResult(Y.cardId,$.elementId,$.element);if(!X.landed){let z=Y.rows.get($.key);if(Q&&!Z&&!$.terminal&&!Y.pendingSettings&&!tQ(X)&&z?.status==="running"&&$.status===z.status&&$.kind===z.kind&&$.summary===z.summary&&$.progressState===z.progressState)return B(`agent: task progress refresh failed task=${$.key}: ${R3("agent task row update",X).message}`),!1;if(!tQ(X)||Y.rows.size===1)throw R3("agent task row update",X);let H=Y;await this.seal(H,!0);let G=this.tails.get($.chatId);if(G)await this.seal(G);Y=await this.create($),H.rows.delete($.key),H.settled.delete($.key);try{let W;if(!await this.deps.deleteElementChecked(H.cardId,$.elementId,(K)=>{W=K})){let K=R3("agent moved task row deletion",{landed:!1,failure:W});throw Error(`${K.message}; the previous card may still show its earlier state`)}}catch(W){V.push(String(W))}try{await this.settings(H)}catch(W){V.push(String(W))}}if(Y.rows.set($.key,$),Z)Y.settled.add($.key);else Y.settled.delete($.key);try{await this.settings(Y)}catch(z){V.push(String(z))}if(V.length)throw Error(V.join("; "));return!0})}closeChat($){return R$($,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,J=await this.deps.sendCard($.chatId,{schema:"2.0",config:{update_multi:!0,streaming_mode:!$.terminal,summary:{content:$.summary}},body:{elements:[$.element]}},(V)=>{Z=V});if(!J)throw Error(`agent card creation failed: ${v(Z)}`);let Q=await this.deps.convertMessageToCard(J);this.deps.recordCardCreated(Q,1);let Y={cardId:Q,messageId:J,chatId:$.chatId,rows:new Map,settled:new Set,sealed:$.dedicated===!0};if(this.attach(Y,$),!$.dedicated)this.tails.set($.chatId,Y);return 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,Q={config:{streaming_mode:!J,summary:{content:nQ([...$.rows.values()])}}},Y=JSON.stringify(Q);if(Y!==$.settingsJson){let V;if($.pendingSettings=!0,!await this.deps.patchSettingsChecked($.cardId,Q,(X)=>{V=X}))throw R3("agent card settings update",{landed:!1,failure:V});$.settingsJson=Y,$.pendingSettings=!1}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 VK($){let{cardMessageId:Z,presentationErrors:J,promptArtifact:Q,...Y}=$;return{key:`run:${$.runId}`,chatId:$.chatId,elementId:j6($.runId),dedicated:$.owner?.kind==="project",element:iQ($),summary:_6($),kind:$.owner?.kind==="project"?"project":"delegated",status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",progressState:rO("sha256").update(JSON.stringify({...Y,workers:Y.workers.map(({steps:V,usage:X,durationMs:z,outputArtifact:H,...G})=>G)})).digest("hex"),attach:(V)=>{$.cardMessageId=V}}}function tQ($){return v4($.failure?.code,$.failure)}function $A($,Z){return $.status==="running"&&Z.status==="running"&&Object.keys({...$,...Z}).every((J)=>J==="steps"||J==="usage"||J==="lastToolName"||$[J]===Z[J])}function R3($,Z){return Error(`${$} MISS: ${v(Z.failure)}`)}var eO=50;var rQ=N(()=>{M$();G1();DZ();h()});function XK(){return new T3(eQ)}var eQ;var $Y=N(()=>{rQ();G1();$0();eQ={sendCard:i,getChatTailMessageId:VJ,convertMessageToCard:l$,recordCardCreated:E$,getElementCount:r9,addElementResult:f4,replaceElementResult:LG,deleteElementChecked:qG,cancelSummary:a0,patchSettingsChecked:k0,dispose:q$}});function ZA(){return JSON.stringify([t5(),rX(),d0().map(($)=>[$.id,$.enabled,$.spawnRevision,$.usageAccount]),y.list().map(($)=>[$.id,$.name,$.revision])])}function ZY(){let $=ZA();if(E3?.key===$)return E3.promise;let Z=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],J=(z)=>Z.includes(z)?Z.indexOf(z):Z.length,Q=d0().filter((z)=>z.enabled||z.kind==="codex-subscription"&&y.list().some((H)=>H.id!=="default")).sort((z,H)=>J(z.id)-J(H.id)),Y=new Set,V=[];for(let z of Q){if(z.kind==="codex-subscription"){V.push(O7().then((W)=>W.entries.filter((K)=>!K.duplicateOf).map((K)=>({id:`codex:${K.account.id}`,label:`Codex·${K.account.name}`,usage:b9(K.usage)}))));continue}let H=z.usageAccount?.id??xH(z.id);if(Y.has(H))continue;Y.add(H);let G=z.usageAccount?.label??(H==="glm"?"GLM Coding Plan":H==="deepseek"?"DeepSeek":z.kind==="claude-subscription"?"Claude 订阅":z.display);V.push(Promise.resolve().then(()=>z.readUsage()).catch((W)=>{let K=W instanceof Error?W.message:String(W);return B(`account usage ${H} MISS: ${K}`),{state:"network",windows:[],reason:K}}).then((W)=>[{id:H,label:G,usage:W}]))}let X=Promise.all(V).then((z)=>z.flat()).finally(()=>{if(E3?.promise===X)E3=void 0});return E3={key:$,promise:X},X}var E3;var zK=N(()=>{j0();bJ();p8();X0();n9();J$();h()});function HK($){let Z=[];for(let J of $.matchAll(JA)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function L6($,Z=process.platform){if(Z!=="win32")return $;let J=QA.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var JA,QA;var JY=N(()=>{JA=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;QA=/^\/([a-zA-Z])\//});function KK($){if(GK.test($))return{marker:"start",body:$.replace(GK,"")};if(WK.test($))return{marker:"end",body:$.replace(WK,"")};return{marker:"none",body:$}}var GK,WK;var BK=N(()=>{GK=/^>{3,}[ \t]?/,WK=/^<{3,}[ \t]?/});async function jK($,Z,J,Q,Y){let{marker:V,body:X}=KK(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)YY($,"reopen");return $.multiMsgBuffer=[],QY($,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}QY($,X,J,Q,Y);let{multiMsgBuffer:z,multiMsgReactions:H}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await VA($,z,H),!0}if($.multiMsgBuffer!==null)return QY($,Z,J,Q,Y),!0;return!1}function QY($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)YA($,Y)}function YA($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await X$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else g0(Z,J)})()}async function VA($,Z,J){for(let[X,z]of J)if(z)g0(X,z);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 k($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((H)=>`[file: ${H}]`).join(" ")+`
240
+ `)}}function VA($){return{tag:"column_set",columns:[dQ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),dQ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),dQ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function dQ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function XA($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function QK($){return $==="completed"||$==="failed"||$==="cancelled"}function YK($){let Z=E2($.owner?.kind==="project"?"project":"delegated");switch($.status){case"completed":return`✅ ${Z}完成`;case"failed":return`❌ ${Z}失败`;case"cancelled":return`\uD83D\uDED1 ${Z}已取消`;case"needs_input":return $.owner?.kind==="project"?"❗ 项目任务不支持交互提问":`❓ ${Z}等待主 Agent 回复`;case"queued":return`⏳ ${Z}等待执行`;case"running":return $.workers.length>0&&$.workers.every((J)=>QK(J.status))?`⏳ ${Z}正在收尾`:`⏳ ${Z}正在执行`}}function B1($){return"`"+$.replace(/`/g,"\\`")+"`"}function o$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function VK($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var $K=8000;var XK=R(()=>{h0();pJ()});function w2($){return zA.has($)?$:null}function P6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function d4($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function k2($){return String($?.subject??$?.content??"").trim()}function oQ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function GK($){return`subj:${$}`}function zK($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function KA($){let Z=k2($);if(!Z)return null;return{id:d4($)||GK(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:oQ($)??"pending"}}function sQ($,Z,J,Q){if(Z==="TaskList"){let Y=P6(Q),V=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(V===null)return $;let X=[];for(let z of V){let H=KA(z);if(H)X.push(H)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let G=P6(Q),W=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,K=$;return Y.forEach((j,_)=>{let D=k2(j);if(!D)return;let P=W?.[_],L=P&&d4(P)||zK(Q??"");K=HK(K,L,D,j)}),K}let V=P6(Q),X=V?.task??V,z=d4(X)||zK(Q??""),H=k2(X)||k2(J);if(!H)return $;return HK($,z,H,J)}if(Z==="TaskUpdate"){let Y=d4(J);if(!Y)return $;let V=oQ(J);if(V==="deleted")return $.filter((z)=>z.id!==Y);let X=k2(J);if($.some((z)=>z.id===Y))return $.map((z)=>z.id===Y?{...z,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:z);return $}if(Z==="TaskGet"){let Y=P6(Q),V=Y?.task??Y,X=d4(V)||d4(J);if(!X)return $;let z=$.find((W)=>W.id===X),H=k2(V)||z?.subject||k2(J);if(!H)return $;let G={id:X,subject:H,description:typeof V?.description==="string"?V.description:z?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:z?.activeForm,status:oQ(V)??z?.status??"pending"};return z?$.map((W)=>W.id===X?G:W):[...$,G]}return $}function HK($,Z,J,Q){let Y=Z||GK(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 tQ($){let Z=$.filter((V)=>V.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let V of Z){let X=GA[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 WK($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let z=parseInt(X,10);return Number.isNaN(z)?Number.MAX_SAFE_INTEGER:z},V=[...J].sort((X,z)=>{let H=Y(X.id)-Y(z.id);return H!==0?H:X.id.localeCompare(z.id)});for(let X of V.slice(0,12)){let z=WA[X.status],H=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${z} ${H||"(空)"}`)}if(V.length>12)Q.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
241
+ `)}function m1($,Z,J,Q){let Y=HA[J.name],V=tQ(Z),X=`${J.status} \uD83D\uDD27 ${Y}: ${V}`;return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:WK(Z,Q)}]}}function v2($){return{tag:"collapsible_panel",element_id:C.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${tQ($)}`}},expanded:!0,elements:[{tag:"markdown",content:WK($)}]}}var zA,HA,GA,WA;var KK=R(()=>{h0();zA=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);HA={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},GA={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},WA={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var M$=R(()=>{h0();I7();HW();wW();sW();eW();XK();KK();tJ()});import{createHash as BA}from"node:crypto";class E3{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(BK($))}async update($,Z=!1,J=!1){await this.updateRow(BK($),Z,!1,J)}syncBackground($,Z,J){return R$($,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,z=Q.get(X);if(z?.task===V&&!z.pendingSettings)continue;let H=z&&D$(z.task)&&!D$(V),G=(z?.version??0)+(H?1:0),W=`background:${Z}:${X}:${G}`,K={key:W,chatId:$,elementId:X3.panel(W),element:sJ({...V,id:W}),summary:f7(V),kind:H3(V),status:V.status,terminal:D$(V)};try{if(!z||H)await this.addRow(K);else{let j=!z.pendingSettings&&_A(z.task,V);if(!await this.updateRow(K,K.terminal,!0,j))continue}Q.set(X,{task:V,version:G})}catch(j){if(this.byTask.get(W)?.rows.get(W)===K)Q.set(X,{task:V,version:G,pendingSettings:!0});Y.push(j)}}if(Y.length)throw AggregateError(Y,Y.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return R$($.chatId,async()=>{if(this.byTask.get($.key)){await this.updateRow($,$.terminal,!0);return}let J=$.dedicated?void 0:this.tails.get($.chatId);if(J){if(await this.deps.getChatTailMessageId($.chatId)===J.messageId&&this.deps.getElementCount(J.cardId)<jA){let Y=await this.deps.addElementResult(J.cardId,$.element);if(Y.landed){this.attach(J,$),await this.settings(J);return}if(!rQ(Y))throw T3("agent card append",Y)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1,Q=!1){return R$($.chatId,async()=>{let Y=this.byTask.get($.key);if(!Y)return!0;if(Y.settled.has($.key)&&!J){if(Z)await this.settings(Y);return!0}if(Y.settled.size===Y.rows.size)Y.settingsJson=void 0;let V=[],X=await this.deps.replaceElementResult(Y.cardId,$.elementId,$.element);if(!X.landed){let z=Y.rows.get($.key);if(Q&&!Z&&!$.terminal&&!Y.pendingSettings&&!rQ(X)&&z?.status==="running"&&$.status===z.status&&$.kind===z.kind&&$.summary===z.summary&&$.progressState===z.progressState)return B(`agent: task progress refresh failed task=${$.key}: ${T3("agent task row update",X).message}`),!1;if(!rQ(X)||Y.rows.size===1)throw T3("agent task row update",X);let H=Y;await this.seal(H,!0);let G=this.tails.get($.chatId);if(G)await this.seal(G);Y=await this.create($),H.rows.delete($.key),H.settled.delete($.key);try{let W;if(!await this.deps.deleteElementChecked(H.cardId,$.elementId,(K)=>{W=K})){let K=T3("agent moved task row deletion",{landed:!1,failure:W});throw Error(`${K.message}; the previous card may still show its earlier state`)}}catch(W){V.push(String(W))}try{await this.settings(H)}catch(W){V.push(String(W))}}if(Y.rows.set($.key,$),Z)Y.settled.add($.key);else Y.settled.delete($.key);try{await this.settings(Y)}catch(z){V.push(String(z))}if(V.length)throw Error(V.join("; "));return!0})}closeChat($){return R$($,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,J=await this.deps.sendCard($.chatId,{schema:"2.0",config:{update_multi:!0,streaming_mode:!$.terminal,summary:{content:$.summary}},body:{elements:[$.element]}},(V)=>{Z=V});if(!J)throw Error(`agent card creation failed: ${w(Z)}`);let Q=await this.deps.convertMessageToCard(J);this.deps.recordCardCreated(Q,1);let Y={cardId:Q,messageId:J,chatId:$.chatId,rows:new Map,settled:new Set,sealed:$.dedicated===!0};if(this.attach(Y,$),!$.dedicated)this.tails.set($.chatId,Y);return 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,Q={config:{streaming_mode:!J,summary:{content:aQ([...$.rows.values()])}}},Y=JSON.stringify(Q);if(Y!==$.settingsJson){let V;if($.pendingSettings=!0,!await this.deps.patchSettingsChecked($.cardId,Q,(X)=>{V=X}))throw T3("agent card settings update",{landed:!1,failure:V});$.settingsJson=Y,$.pendingSettings=!1}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 BK($){let{cardMessageId:Z,presentationErrors:J,promptArtifact:Q,...Y}=$;return{key:`run:${$.runId}`,chatId:$.chatId,elementId:_6($.runId),dedicated:$.owner?.kind==="project",element:nQ($),summary:L6($),kind:$.owner?.kind==="project"?"project":"delegated",status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",progressState:BA("sha256").update(JSON.stringify({...Y,workers:Y.workers.map(({steps:V,usage:X,durationMs:z,outputArtifact:H,...G})=>G)})).digest("hex"),attach:(V)=>{$.cardMessageId=V}}}function rQ($){return v4($.failure?.code,$.failure)}function _A($,Z){return $.status==="running"&&Z.status==="running"&&Object.keys({...$,...Z}).every((J)=>J==="steps"||J==="usage"||J==="lastToolName"||$[J]===Z[J])}function T3($,Z){return Error(`${$} MISS: ${w(Z.failure)}`)}var jA=50;var eQ=R(()=>{M$();G1();FZ();h()});function jK(){return new E3($Y)}var $Y;var ZY=R(()=>{eQ();G1();$0();$Y={sendCard:n,getChatTailMessageId:XJ,convertMessageToCard:l$,recordCardCreated:E$,getElementCount:e9,addElementResult:f4,replaceElementResult:AG,deleteElementChecked:NG,cancelSummary:a0,patchSettingsChecked:k0,dispose:q$}});function LA(){return JSON.stringify([r5(),Vz(),d0().map(($)=>[$.id,$.enabled,$.spawnRevision,$.usageAccount]),v.list().map(($)=>[$.id,$.name,$.revision])])}function JY(){let $=LA();if(x3?.key===$)return x3.promise;let Z=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],J=(z)=>Z.includes(z)?Z.indexOf(z):Z.length,Q=d0().filter((z)=>z.enabled||z.kind==="codex-subscription"&&v.list().some((H)=>H.id!=="default")).sort((z,H)=>J(z.id)-J(H.id)),Y=new Set,V=[];for(let z of Q){if(z.kind==="codex-subscription"){V.push(A7().then((W)=>W.entries.filter((K)=>!K.duplicateOf).map((K)=>({id:`codex:${K.account.id}`,label:`Codex·${K.account.name}`,usage:k9(K.usage)}))));continue}let H=z.usageAccount?.id??yH(z.id);if(Y.has(H))continue;Y.add(H);let G=z.usageAccount?.label??(H==="glm"?"GLM Coding Plan":H==="deepseek"?"DeepSeek":z.kind==="claude-subscription"?"Claude 订阅":z.display);V.push(Promise.resolve().then(()=>z.readUsage()).catch((W)=>{let K=W instanceof Error?W.message:String(W);return B(`account usage ${H} MISS: ${K}`),{state:"network",windows:[],reason:K}}).then((W)=>[{id:H,label:G,usage:W}]))}let X=Promise.all(V).then((z)=>z.flat()).finally(()=>{if(x3?.promise===X)x3=void 0});return x3={key:$,promise:X},X}var x3;var _K=R(()=>{j0();kJ();c8();z0();a9();J$();h()});function LK($){let Z=[];for(let J of $.matchAll(PA)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function q6($,Z=process.platform){if(Z!=="win32")return $;let J=qA.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var PA,qA;var QY=R(()=>{PA=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;qA=/^\/([a-zA-Z])\//});function DK($){if(PK.test($))return{marker:"start",body:$.replace(PK,"")};if(qK.test($))return{marker:"end",body:$.replace(qK,"")};return{marker:"none",body:$}}var PK,qK;var FK=R(()=>{PK=/^>{3,}[ \t]?/,qK=/^<{3,}[ \t]?/});async function UK($,Z,J,Q,Y){let{marker:V,body:X}=DK(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)VY($,"reopen");return $.multiMsgBuffer=[],YY($,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}YY($,X,J,Q,Y);let{multiMsgBuffer:z,multiMsgReactions:H}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await FA($,z,H),!0}if($.multiMsgBuffer!==null)return YY($,Z,J,Q,Y),!0;return!1}function YY($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)DA($,Y)}function DA($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await X$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else g0(Z,J)})()}async function FA($,Z,J){for(let[X,z]of J)if(z)g0(X,z);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 b($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((H)=>`[file: ${H}]`).join(" ")+`
241
242
  `:"")+X.text}).join(`
242
243
 
243
- `),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 YY($,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)g0(Q,Y);X$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var _K=N(()=>{$0();h();BK()});import{mkdtemp as zA,rm as HA,writeFile as GA}from"node:fs/promises";import{createRequire as WA}from"node:module";import{tmpdir as KA}from"node:os";import{join as PK}from"node:path";function FA($){let Z=FK.get($);if(Z)return Z;let{liteAdaptor:J}=y2("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Q}=y2("mathjax-full/js/handlers/html.js"),{mathjax:Y}=y2("mathjax-full/js/mathjax.js"),{TeX:V}=y2("mathjax-full/js/input/tex.js"),{AllPackages:X}=y2("mathjax-full/js/input/tex/AllPackages.js"),{SVG:z}=y2("mathjax-full/js/output/svg.js"),H=J({fontSize:$});Q(H);let G=Y.document("",{InputJax:new V({packages:X}),OutputJax:new z({fontCache:"none"})}),W={adaptor:H,doc:G};return FK.set($,W),W}function UK($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function UA($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function MA($,Z=zY,J=!0){try{let Q=Z*BA,{adaptor:Y,doc:V}=FA(Z),X=V.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),z=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(z)){let n=z.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(n)}let H=z.indexOf("<svg"),G=z.lastIndexOf("</svg>");if(H<0||G<0)throw Error("MathJax returned no SVG");let W=z.slice(H,G+6),K=W.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let j=UK(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),_=UK(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),D=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!D)throw Error("MathJax SVG missing viewBox");let L=D.trim().split(/[\s,]+/).map(Number);if(L.length!==4||L.some((n)=>!Number.isFinite(n))||L[2]<=0||L[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[P,F,U,A]=L,M=/<text\b/.test(W)?qA:0,O=`${P} ${F} ${U+M} ${A}`,R=j*Q,w=M*(R/U),T=Math.max(1,Math.ceil(R+w)),f=Math.max(1,Math.ceil(_*Q)),u=jA-VY*2,C=Math.min(1,u/T),g=Math.max(1,Math.round(T*C)),Y0=Math.max(1,Math.round(f*C));if(C<1&&Y0<_A)throw Error(`formula would be unreadable after width cap (${g}x${Y0})`);let e=g+VY*2,E=Y0+qK*2,x=W.slice(K.length,-6).replace(/currentColor/g,LK).replace(/font-family="serif"/g,`font-family="${DA}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${E}" viewBox="0 0 ${e} ${E}" style="color:${LK}">`,`<rect x="0" y="0" width="${e}" height="${E}" rx="6" fill="${NK}"/>`,`<svg x="${VY}" y="${qK}" width="${g}" height="${Y0}" viewBox="${UA(O)}" preserveAspectRatio="xMidYMid meet">`,x,"</svg>","</svg>"].join(""),width:e,height:E}}catch(Q){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function OA($,Z=zY,J=!0){let Q=MA($,Z,J);if(!Q)return null;try{let{Resvg:Y}=y2("@resvg/resvg-js"),X=new Y(Q.svg,{background:NK,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:DK,sansSerifFamily:DK}}).render().asPng(),z=new DataView(X.buffer,X.byteOffset,X.byteLength),H=z.getUint32(16),G=z.getUint32(20);if(H!==Q.width||G!==Q.height)throw Error(`PNG dimensions ${H}x${G} != SVG ${Q.width}x${Q.height}`);return{png:X,width:H,height:G}}catch(Y){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function AA($){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 MK($,Z){let J=[],Q=(W,K,j)=>{let _=W[0],D=K.trim();if(!D)return;J.push({start:Z+W.index,end:Z+W.index+_.length,tex:D,raw:_,display:j})},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 z=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=z.exec($))!==null){let W=(Y[1]??"").trim();if(AA(W))Q(Y,W,!1)}J.sort((W,K)=>W.start-K.start||K.end-W.end);let H=[],G=-1;for(let W of J){if(W.start<G)continue;H.push(W),G=W.end}return H}function RK($){let Z=EZ($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...MK($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...MK($.slice(Q),Q));return J}function NA($){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(OK[Q])return OK[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 xA($){let Z=AK.get($);if(Z!==void 0)return Z;return Z=TA++,AK.set($,Z),Z}function SA($,Z){return`${LA}\x00${xA(Z)}\x00${$}`}function CA($){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 bA($,Z){let J=SA($,Z),Q=v2.get(J);if(Q)return Q;let Y=XY.get(J);if(Y)return Y;let V=(async()=>{let X=OA($,zY,!0);if(!X)return null;let z=null;try{z=await zA(PK(KA(),"lodestar-math-"));let H=PK(z,`formula-${CA($)}.png`);await GA(H,X.png);let G=await Z(H,{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(v2.has(J))v2.delete(J);v2.set(J,W);while(v2.size>EA){let K=v2.keys().next().value;if(typeof K!=="string")break;v2.delete(K)}return W}catch(H){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${H}`),null}finally{if(z)try{await HA(z,{recursive:!0,force:!0})}catch(H){B(`math-render: temp cleanup failed for ${z}: ${H}`)}}})();XY.set(J,V);try{return await V}finally{XY.delete(J)}}function kA($,Z,J){let Q=$.width<=PA;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 TK($,Z={}){let J=RK($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??RA,Y=await Promise.all(J.map(async(W)=>{if(!W.display){let K=NA(W.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await bA(W.tex,Q)}})),V=[],X="",z=0,H=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],j=Y[W];if(X+=$.slice(z,K.start),j.unicode!==null){X+=j.unicode,z=K.end;continue}let _=j.uploaded;if(!_){X+=K.raw,z=K.end;continue}G(),V.push(kA(_,K,H++)),z=K.end}if(X+=$.slice(z),G(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:H}}function HY($){return RK($).length>0}var y2,BA=0.5,zY=22,LK="#1F2329",NK="#F7F8FA",VY=12,qK=8,jA=720,_A=14,PA=278,LA="v4-native-cjk-tail-pad",qA=1100,DK,DA="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",FK,OK,RA=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => ($0(),Z0));return Z($)},AK,TA=1,v2,XY,EA=512;var EK=N(()=>{h();y2=WA(import.meta.url),DK=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",FK=new Map;OK={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:"Ω"};AK=new WeakMap,v2=new Map,XY=new Map});import{readFileSync as vA}from"node:fs";function i4($){return GY.has($)}function S3($){GY.add($)}function C3($){GY.delete($)}function p1(){try{let $={};for(let[Z,J]of m0)$[Z]=J;a(x3,$)}catch($){throw B(`notify-callbacks: save failed (${x3}): ${$}`),$}}function bK(){let $=[],Z;try{Z=vA(x3,"utf8")}catch(J){if(J?.code==="ENOENT")return[];throw B(`notify-callbacks: read failed (${x3}): ${J}`),J}try{let J=JSON.parse(Z);if(!J||typeof J!=="object"||Array.isArray(J))throw Error("notify callback store must be an object");let Q=Date.now()-CK,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(X.dispatchState&&!X.resolvedAt&&!X.unknownAt)X.unknownAt=Date.now(),X.unknownBy={buttonId:X.dispatchState.buttonId,openId:X.dispatchState.openId},X.unknownReason="服务在按钮回调期间中断,无法确认是否送达,禁止自动重试",V++;if(m0.set(X.notifyId,X),(X.replyState?.status==="sending"||X.dispatchState)&&X.unknownAt)$.push(X)}if(B(`notify-callbacks: loaded ${m0.size} registration(s)${Y?`, dropped ${Y} stale`:""}`),V)B(`notify-callbacks: ${V} interrupted callback(s) marked UNKNOWN`);if(Y>0||V>0)p1()}catch(J){throw B(`notify-callbacks: load failed (${x3}): ${J}`),J}return $}function kK($){let Z=Date.now();if(Z-SK>=yA)fA(Z),SK=Z;m0.set($.notifyId,$),p1()}function j1($){return m0.get($)}function wK($,Z,J){let Q=m0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);if(Q.resolvedAt||Q.unknownAt||Q.dispatchState)throw Error("notify callback is already dispatched or finalized");Q.dispatchState={buttonId:Z,openId:J,startedAt:Date.now()};try{p1()}catch(Y){throw delete Q.dispatchState,Y}}function vK($){let Z=m0.get($);if(!Z?.dispatchState)throw Error(`notify callback is not dispatching: ${$}`);let J=Z.dispatchState;delete Z.dispatchState;try{return p1(),{state:"retry"}}catch(Q){Z.dispatchState=J;let Y=`callback failure persistence failed: ${Q instanceof Error?Q.message:Q}`;try{q6($,J.buttonId,J.openId,Y)}catch(V){Z.unknownReason=`${Y}; unknown tombstone persistence also failed: ${V instanceof Error?V.message:V}`}return{state:"unknown",detail:Z.unknownReason??Y}}}function WY($){return[...m0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function b3($,Z){if(!$)return;return WY($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function yK($,Z){return!!Z&&[...m0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function n4($,Z){let J=m0.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{p1()}catch(V){if(Q)J.replyState=Q;else delete J.replyState;if(Y)J.replyMessageIds=Y;else delete J.replyMessageIds;throw V}}function k3($,Z,J){let Q=m0.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,dispatchState:Q.dispatchState};Q.resolvedAt=Date.now(),Q.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Q.unknownAt,delete Q.unknownBy,delete Q.unknownReason,delete Q.dispatchState;try{p1()}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;if(Y.dispatchState!==void 0)Q.dispatchState=Y.dispatchState;throw V}}function q6($,Z,J,Q){let Y=m0.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,p1()}function D6($,Z,J){try{return k3($,Z,J),{state:"complete"}}catch(Q){let V=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{q6($,Z,J,V)}catch(X){let z=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${z}`;let H=m0.get($);if(H)H.unknownReason=V}return{state:"unknown",detail:V}}}function fA($=Date.now()){let Z=$-CK,J=0;for(let[Q,Y]of m0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)m0.delete(Q),J++;if(J>0)p1();return J}async function KY($,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(),xK);try{let X=await SV($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let H;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())H=K.trim().slice(0,500)}else if(G)H=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:H}}let z="";try{z=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${z?` ${z}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${xK}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function fK($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((z)=>z.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 CK=604800000,xK=2500,m0,SK,yA=86400000,GY,x3;var w3=N(()=>{p0();h();H0();x0();m0=new Map,SK=Date.now(),GY=new Set;x3=qV});function F6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function a4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(b3($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(F6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function BY($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Q=J.currentIdx===void 0?void 0:b3($.chatId)?"notification":F6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Q}}function jY($,Z){let J=$.pendingAsks.get(Z),Q=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||a4($,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,z=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(a0(Q.cardId),await T7(Q.cardId,{config:{summary:{content:z}}}),$.currentTurn!==Q||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Y||J.currentIdx===void 0||a4($,Z))return;await L2(Q.messageId,[Q.userOpenId])})().catch((H)=>B(`session "${$.sessionName}": question notification failed: ${H}`))}function U6($){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=BY($,J);if(V.waitingFor)Q.announced=!1,Q.announcementVersion=(Q.announcementVersion??0)+1;F0(Z.cardId,b.tool(Y.i),l4(Y.i,J,Q.questions,"\uD83E\uDD14",V)),jY($,J)}}function hK($){return F6($)!==void 0}async function IK($,Z,J,Q){let Y=F6($);if(!Y){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Q);return}let[V,X]=Y,z=a4($,V);if(z){let G=`${z}。这条文字未提交,请稍后重新发送。`,W;if(!await k($.chatId,G,(K)=>{W=K}))throw Error(`提问等待提示发送失败: ${G}
244
- ${v(W)}`);return}if(await _Y($,V,X.currentIdx,Z,J)&&Q)X$(Q,"CheckMark")}async function gK($,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 mK($,Z,{optionIdx:Q,user:Y})}async function _Y($,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 mK($,Z,{customText:X,user:Y})}function mK($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=a4($,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 z;if(J.customText!==void 0)z=J.customText;else if(J.optionIdx!==void 0){let j=X.options?.[J.optionIdx];if(!j)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;z=j.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[X.question]=z,Q.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let H=Q.questions.length,G=void 0;for(let j=V+1;j<H;j++)if(!Q.answered.has(j)){G=j;break}Q.currentIdx=G;let W=$.currentTurn,K=W?.toolByUseId.get(Z);if(W&&K){let j=l4(K.i,Z,Q.questions,G===void 0?"✅":"\uD83E\uDD14",{currentIdx:G,answered:Q.answered});F0(W.cardId,b.tool(K.i),j)}if(G===void 0)if(Q.requestId)PY($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),U6($);return!0}function PY($,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),U6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var M6=N(()=>{G1();M$();$0();h();w3()});import{isAbsolute as IA}from"node:path";function w0($){if($?.planLiveInserted)return b.planLive;return $?.taskLiveInserted?b.taskBoardLive:b.footer}function gA($){return $==="ImageGeneration"||$==="imageGeneration"}function mA($,Z,J){if(J||!gA($))return null;let Q=L6(Z.trim());return IA(Q)?Q:null}function pA($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function pK($,Z,J){return $==="read"?L3(Z,J):P3(Z,J)}function cK($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=pA(J);if(Y&&$.currentTurn.openBatchI!==null){let H=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(H);if(G&&G.kind===Y){let W=G.items.length;G.items.push({toolUseId:Z,input:Q,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Q,batchSlot:W});let K=Y==="read"?L3(H,G.items):P3(H,G.items);F0($.currentTurn.cardId,b.tool(H),K),O6($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let V=k2(J);if(V){let H=$.currentTurn;if(V==="TaskCreate"&&!H.taskBoardResetThisTurn)$.taskBoard=[],H.taskBoardResetThisTurn=!0;if(!H.taskLiveInserted)H.taskLiveInserted=!0,T0(H.cardId,w2($.taskBoard),{type:"insert_before",targetElementId:b.footer});else B0(H.cardId,b.taskBoardLive,w2($.taskBoard),{notifyCardFailure:!1});let G=V==="TaskCreate";if(G)H.taskUpdateI=null;else H.taskCreateI=null;let W=(G?H.taskCreateI:H.taskUpdateI)===null;if(W)if(G)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let K=G?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(Z,{i:K,name:J,input:Q});let j=m1(K,$.taskBoard,{name:V,status:"⏳"});W?T0(H.cardId,j,{type:"insert_before",targetElementId:w0(H)}):F0(H.cardId,b.tool(K),j),O6(H,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let H=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:H}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let G=Y==="read"?L3(X,H):P3(X,H);T0($.currentTurn.cardId,G,{type:"insert_before",targetElementId:w0($.currentTurn)},void 0,"capacity"),O6($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let H=Array.isArray(Q?.questions)?Q.questions:[],G=H.length>0?0:void 0,W=new Map;$.pendingAsks.set(Z,{questions:H,i:X,answers:{},answered:W,currentIdx:G});let K=l4(X,Z,H,"\uD83E\uDD14",BY($,Z));T0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:w0($.currentTurn)}),jY($,Z);return}let z=a$(X,J,Q,null,"⏳");T0($.currentTurn.cardId,z,{type:"insert_before",targetElementId:w0($.currentTurn)},void 0,"capacity"),O6($.currentTurn,J,Q)}function O6($,Z,J){if(!$)return;let Q=y1(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,V=x2(Z),X=Y?`\uD83D\uDD27 ${V}: ${Y}`:`\uD83D\uDD27 ${V}`;h4($.cardId,X)}function lK($,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(([,W])=>W!==void 0))};let X=typeof J==="string"?J:Array.isArray(J)?J.map((W)=>W?.text??JSON.stringify(W)).join(`
245
- `):JSON.stringify(J);if(V.output=X,V.isError=Q,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let z=mA(V.name,X,Q);if(z){cA($,$.currentTurn,V,z),f2($);return}if(V.name==="AskUserQuestion"){f2($);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=Q;let j=pK(W.kind,V.i,W.items);F0($.currentTurn.cardId,b.tool(V.i),j)}f2($);return}let H=k2(V.name);if(H){lA($,V,H,V.input,X,Q,V.resolvedNote);return}let G=a$(V.i,V.name,V.input,X,Q?"❌":"✅",V.resolvedNote);F0($.currentTurn.cardId,b.tool(V.i),G),f2($)}function cA($,Z,J,Q){if(Z.outboundSeenPaths.has(Q))return;Z.outboundSeenPaths.add(Q);let Y=Z.cardId,V=b.tool(J.i),X=Z.imageDeliveryInflight??=new Map,z=X.get(Y)??new Set;X.set(Y,z);let H=[],G=(async()=>{let W=null;try{W=await XJ(Q,(L)=>{H.push(`图片上传:${v(L)}`)})}catch(L){H.push(`图片上传:${v(L)}`),B(`generated image upload failed: ${L}`)}if(W){let L=!1;try{L=await B0(Y,V,a$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1,onFailure:(P)=>{H.push(`图片嵌入:${v(P)}`)}})}catch(P){H.push(`图片嵌入:${v(P)}`),B(`generated image embed failed: ${P}`)}if(L){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 K,j=W?await X7($.chatId,W,(L)=>{K=L})!==null:await l9($.chatId,Q);if(j)Z.outboundSentPaths.add(Q);else B(`generated image delivery failed: ${Q}`);if(!j&&W)H.push(`图片发送:${v(K)}`);J.resolvedNote=[j?"图片已单独发送。":"图片发送失败。",...H].join(`
246
- `);let _,D=!1;try{D=await B0(Y,V,a$(J.i,J.name,J.input,J.output??null,j?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1,onFailure:(L)=>{_=L}})}catch(L){_=L}if(!D)B(`generated image status write failed card=${Y} path=${Q}: ${v(_)}
247
- ${J.resolvedNote}`);if(!j&&W)await k($.chatId,`❌ 生成图片发送失败:${H.join(`
248
- `)}`)})().catch(async(W)=>{B(`generated image delivery failed: ${W}`),await k($.chatId,`❌ 生成图片发送失败:${[...new Set([...H,v(W)])].join(`
249
- `)}`)});z.add(G),G.finally(()=>{if(z.delete(G),!z.size)X.delete(Y)}).catch((W)=>B(`generated image failure notice failed: ${W}`))}async function LY($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Q)=>[...Q]);await Promise.allSettled(J)}function lA($,Z,J,Q,Y,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=oQ($.taskBoard,J,Q,Y);let z=m1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(F0($.currentTurn.cardId,b.tool(Z.i),z),$.currentTurn.taskLiveInserted)B0($.currentTurn.cardId,b.taskBoardLive,w2($.taskBoard),{notifyCardFailure:!1});f2($)}function f2($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function qY($,Z,J,Q,Y,V=$.currentTurn){let X=V;if(!X)return;for(let[z,H]of Q){if(X.toolByUseId.has(z))continue;let G=H.batchSlot??null,W=H.input,K,j;if(G!=null){let U=Y.get(H.i)?.items[G];if(!U)continue;W=U.input,K=U.output,j=U.isError}else K=H.output??null,j=H.isError??!1;let _=K!=null,D=y4(Z,b.tool(H.i));if(_&&!D)continue;if(G!=null){let U=Y.get(H.i)?.kind;if(!U)continue;let A=X.toolCount++,M={toolUseId:z,input:W,output:K,isError:j};X.toolBatches.set(A,{kind:U,items:[M]}),X.toolByUseId.set(z,{...H,i:A,batchSlot:0}),T0(J,pK(U,A,[M]),{type:"insert_before",targetElementId:w0(X)});continue}let L=k2(H.name);if(L){let U=L==="TaskCreate";if(U)X.taskUpdateI=null;else X.taskCreateI=null;let A=(U?X.taskCreateI:X.taskUpdateI)===null;if(A)if(U)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let M=U?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(z,{...H,i:M});let O=!_?"⏳":j?"❌":"✅",R=m1(M,$.taskBoard,{name:L,status:O},H.resolvedNote);A?T0(J,R,{type:"insert_before",targetElementId:w0(X)}):F0(J,b.tool(M),R);continue}let P=X.toolCount++;X.toolByUseId.set(z,{...H,i:P});let F=!_?"⏳":j?"❌":"✅";T0(J,a$(P,H.name,H.input,K,F,H.resolvedNote,H.imageKey),{type:"insert_before",targetElementId:w0(X)})}}var uK=N(()=>{JY();G1();M$();$0();h();M6()});async function dK($,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(G){return B(`session "${$.sessionName}": permission response ${Z} failed: ${G}`),{ok:!1,message:`权限决定发送失败: ${G instanceof Error?G.message:G}`}}$.pendingPermissions.delete(Z);let z=$.currentTurn,H=z?.toolByUseId.get(Y.toolUseId);if(z&&H){let G=k2(H.name);if(J==="deny"){let W=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,K=G?m1(H.i,$.taskBoard,{name:G,status:"❌"},W):a$(H.i,H.name,H.input,W,"❌");F0(z.cardId,b.tool(H.i),K)}else{let W=J==="allow_always"?"始终允许":"已允许";H.resolvedNote=`✅ **${W}** by ${Q||"匿名"}`;let K=G?m1(H.i,$.taskBoard,{name:G,status:"⏳"},H.resolvedNote):a$(H.i,H.name,H.input,null,"⏳",H.resolvedNote);F0(z.cardId,b.tool(H.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 iK($,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)PY($,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=NQ(Y.i,Y.name,Y.input,Z.request_id);if(F0(J.cardId,b.tool(Y.i),V),J.userOpenId&&J.messageId){let X=y1(Y.name,Y.input),z=x2(Y.name),H=X&&X.length>30?X.slice(0,30)+"…":X,G=H?`\uD83D\uDD10 等审批: ${z} · ${H}`:`\uD83D\uDD10 等审批: ${z}`;(async()=>{a0(J.cardId),await T7(J.cardId,{config:{summary:{content:G}}}),await L2(J.messageId,[J.userOpenId])})()}}var nK=N(()=>{G1();M$();$0();h();M6()});function nA($){let Z=!1,J=()=>{},Q=()=>{},Y=$.sessionId,V=()=>{$.off("context_compacted",H),$.off("exit",G),$.off("error",W)},X=(j)=>{if(Z)return;Z=!0,V(),J(j)},z=(j)=>{if(Z)return;Z=!0,V(),Q(j)},H=(j)=>{if(j.phase==="start")return;if(j.threadId&&Y&&j.threadId!==Y)return;X(j)},G=()=>z(Error(`${$.provider} process exited before context compaction completed`)),W=(j)=>z(j instanceof Error?j:Error(String(j))),K=new Promise((j,_)=>{J=j,Q=_});return $.on("context_compacted",H),$.once("exit",G),$.once("error",W),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function aA($,Z){let J=[],Q=new Set,Y=(z,H)=>{let G=H.threadId??Z;if(G&&z.threadId&&z.threadId!==G)return!1;if(H.turnId)return z.turnId===H.turnId;return!0},V=(z)=>{for(let H=J.length-1;H>=0;H--){let G=J[H];if(G&&Y(G,z))return G}return null},X=(z)=>{if(Z&&z.threadId&&z.threadId!==Z)return;let H={usage:z.usage,contextWindow:z.contextWindow,threadId:z.threadId,turnId:z.turnId};J.push(H);for(let G of[...Q])if(Y(H,G.notice))G.finish(H)};return $.on("token_usage",X),{waitFor(z,H){let G=V(z);if(G)return Promise.resolve(G);return new Promise((W)=>{let K=null,j={notice:z,finish:(_)=>{if(K)clearTimeout(K);Q.delete(j),W(_)}};K=setTimeout(()=>j.finish(null),H),Q.add(j)})},cancel(){$.off("token_usage",X);for(let z of[...Q])z.finish(null)}}}function oA($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=I7($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=g7($.contextWindow);return` · \uD83E\uDDE0 ${oG(Z,J)} (${m7(Z,J)})`}async function aK($){$.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 k($.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 k($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let G=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(G)await $.closeStatusCard(G,"⏳ 上下文压缩已在进行中");else await k($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Q=J.sessionId?S0(J.sessionId):"",Y=$.withModel(Q?`\uD83E\uDDE0 压缩上下文 thread=${Q}`:"\uD83E\uDDE0 压缩上下文…"),V=await $.openStatusCard("compact",Y,"orange"),X=async(G)=>{if(V)await $.closeStatusCard(V,G);else await k($.chatId,G)},z=nA(J),H=aA(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let G=await z.promise,W=await H.waitFor(G,iA),K=G.threadId?` thread=${S0(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${oA(W)}`))}catch(G){if(z.cancel(),G instanceof W2)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${S(G)}`)}finally{H.cancel(),$.manualContextCompactionPending=!1}}var iA=1500;var oK=N(()=>{_0();$0()});import{randomUUID as tA}from"node:crypto";function sK($,Z){return{ok:!1,message:Z,card:z6($.sessionName,!1,Z)}}async function FY($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return sK($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${S(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof K4&&J.error.confirmedModel!==null?Z.model:null,Z.confirmedEffort=J.ok?Z.effort:null;let Q=J.ok?null:S(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=`模型和思考档位已应用,但保存选择失败:${S(Y)}`}if(Q!==null)return Z.phase="failed",Z.error=`${Q}。本次完整设置未保存,后续输入暂停;请重新发送 md 完成选择,或 restart 恢复已保存的设置。`,B(`session "${$.sessionName}": model settings incomplete: ${Z.error}`),sK($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${i0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:M3({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:OY($,Z.provider)})}}async function rA($,Z,J,Q,Y,V,X){let z,H=new Promise((D)=>{z=D}),G={proc:Z,provider:Z.provider,model:J,effort:Y,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(D){G.cancelled=D,z({ok:!1,error:Error(D)})}};$.modelSettingsChange=G;let W=Promise.resolve().then(()=>Z.setModelSettings(Q,Y)).then(()=>({ok:!0}),(D)=>({ok:!1,error:D})),K=Promise.race([W,H]),j=Symbol("model-settings-pending"),_;try{let D=await Promise.race([K,new Promise((P)=>{_=setTimeout(()=>P(j),20000)})]);if(D!==j)return await FY($,G,D);let L=`正在等待 ${i0(Z.provider)} 确认 ${J} / ${Y},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:L,card:z6($.sessionName,!0,L),completion:K.then((P)=>$.finishModelSettingsChange(G,P))}}finally{clearTimeout(_)}}function eA($){let Z=$.currentTokenSource();return d0().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 UY($,Z,J=Z.models){let Q=$.currentModelLabel(),Y=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let z=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:z,efforts:X.efforts.map((H)=>({effort:H,description:H==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:H===X.defaultEffort,selected:z&&Y===H}))}})}async function tK($){let Z=tA(),J=eA($);$.modelPanels.set(Z,{models:[]});let Q,Y=await i($.chatId,SQ({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}),(V)=>{Q=V});if(!Y)$.modelPanels.delete(Z),await I($.chatId,`❌ 模型面板发送失败:${v(Q)}`);else{let V=$.modelPanels.get(Z);if(V)V.messageId=Y}}async function MY($,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??"刷新失败"}`};if(Y.modelCatalogState?.status==="idle"||Y.modelCatalogState?.status==="loading")return{ok:!1,message:"模型目录缓存尚未就绪,后台刷新中"};let X=UY($,Y),z=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Q,messageId:z,mode:"select",editable:!!Y.modelSelection,sourceRevision:Y.spawnRevision}),A6($,V,Q,0)}async function A6($,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/DY));if(!Number.isInteger(Q)||Q<0||Q>=V)return{ok:!1,message:"模型页码无效"};return Y.models=Y.catalog.slice(Q*DY,(Q+1)*DY),Y.page=Q,Y.totalPages=V,{ok:!0,message:"",card:CQ({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 rK($,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:UY($,Y,V),sourceId:J,messageId:Q.messageId,mode:"add",editable:!0,sourceRevision:Y.spawnRevision}),A6($,Z,J,0)}async function eK($,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((z)=>z.model===Q))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Y==="delete"){let z=[...S$.all].filter((H)=>H.currentTokenSource()?.id===J&&H.currentModelLabel()===Q.replace(/\[1m\]$/,""));if(z.length)return{ok:!1,message:`补录模型仍被会话 ${z.map((H)=>H.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Y==="delete")await bG(J,Q,$.codexAccountId());else await SG(J,Q,Y,$.codexAccountId());for(let H of S$.all)for(let[G,W]of H.modelPanels)if(W.sourceId===J&&(H!==$||G!==Z))H.modelPanels.delete(G);return{...await MY($,J,Z),message:Y==="add"?"模型已显示":Y==="delete"?"补录模型已删除":"模型已隐藏"}}catch(z){return{ok:!1,message:`模型列表更新失败:${S(z)}`}}}async function $B($,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:kQ($.sessionName,Y.display,V)}}async function ZB($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),V=$.tokenSource(Q.sourceId),X=[],z=async(_)=>{if(!Q.cardMessageId)return!1;let D="",L=!1,P=!1;try{D=await l$(Q.cardMessageId),E$(D,1);let F;if(L=await B0(D,b.modelPanel,_,{notifyCardFailure:!1,onFailure:(A)=>{F=A}}),!L)throw Error(`model panel replace rejected: ${v(F)}`);let U;if(P=await k0(D,{config:{streaming_mode:!1}},(A)=>{U=A}),!P)throw Error(`model panel streaming-off rejected: ${v(U)}`)}catch(F){B(`model-custom: card update MISS (${F?.message??F})`),X.push(S(F))}finally{if(D){if(!P)try{let F;if(P=await k0(D,{config:{streaming_mode:!1}},(U)=>{F=U}),!P)X.push(`model panel streaming-off rejected: ${v(F)}`)}catch(F){B(`model-custom: streaming-off retry MISS (${F?.message??F})`),X.push(v(F))}if(L&&P)try{await q$(D)}catch(F){B(`model-custom: card dispose MISS (${F?.message??F})`)}else B(`model-custom: retain card state after checked MISS mutation=${L} streamingOff=${P} card=${D.slice(0,12)}`)}}return L&&P},H=async(_,D)=>{if(await z(_))return!0;let P=[...new Set(X)].join(`
250
- `),F=`⚠️ 模型补录结果未能写回原卡。${D}${P?`
251
- ${P}`:""}
252
- 请重新发送 model 打开面板。`;if(!await I($.chatId,F))B(`model-custom: visible fallback send MISS (${D})`);return!1},G=(_)=>H(A3(!1,Y,_),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${_}。`);if(!V||!V.enabled)return await G("账号不可用"),!0;if(!Y)return await G("模型名为空"),!0;if(V.models.some((_)=>_.model.toLowerCase()===Y.toLowerCase()))return await H(A3(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;try{await CG(V.id,Y,$.codexAccountId())}catch(_){return B(`model-custom: config/refresh MISS (${S(_)})`),await G(`配置写入或模型刷新失败:${S(_)}`),!0}B(`model-custom: ${V.id} 补录 ${Y} by ${J}(记录已持久化)`);for(let _ of S$.all)for(let[D,L]of _.modelPanels)if(L.sourceId===V.id&&(_!==$||D!==Q.panelId))_.modelPanels.delete(D);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await G(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let K=UY($,W),j=K.find((_)=>_.model===Y);if(!j)return await G("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Q.panelId,{models:K,messageId:Q.cardMessageId}),j.unavailableReason||!j.efforts.length)return await H(A3(!0,Y,`**MISS**:${j.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Y} 已补录,能力尚未确认。`),!0;if(j.efforts.length===1){let _=await $.onModelEffortSelect(j.model,j.efforts[0].effort,Q.panelId,J,j.provider),D=(L)=>H(L.pending?O3(!0,L.message):L.ok?W6({sessionName:$.sessionName,provider:j.provider,model:j.model,effort:j.efforts[0].effort,scope:OY($,j.provider??"codex")}):O3(!1,L.message),L.message);if(await D(_),_.completion)_.completion.then(D).catch(async(L)=>{let P=`模型补录后的切换结果呈现失败:${S(L)}`;B(`model-custom: ${P}`),await I($.chatId,`❌ ${P}`)});return!0}return await H(G6({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:j}),`✅ 模型 ${Y} 已补录成功。`),!0}async function JB($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:H6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:H6($.sessionName)}}function $N($,Z){return g$(Z?.provider)?Z.provider:W4($)}function OY($,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`下次启动 ${i0(Z)} 时使用。`}async function QB($,Z,J="",Q="",Y=null){let V=Z.trim();if(!V)return await k($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=$N(V,Y),z=$.modelPanels.get(J.trim())?.models.find((H)=>H.model===V&&(H.provider??"codex")===X);if(!z)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(z.unavailableReason)return{ok:!1,message:z.unavailableReason};if(z.enabled===!1)return{ok:!1,message:`${z.displayName} 未配置,请先点「启用」`};if(z.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(z.efforts.length===1)return AY($,V,z.efforts[0].effort,J,Q,X);return{ok:!0,message:"",card:bQ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:z})}}async function AY($,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(),z=J.trim();if(!X)return{ok:!1,message:"模型为空"};let H=Q.trim(),G=$.modelPanels.get(H),W=g$(V)?V:G?.models.find((O)=>O.model===X)?.provider??W4(X);if(W==="dsh"){if(!O0(z))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(W==="claude"){if(!R0(z))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!_$(z))return{ok:!1,message:"Codex reasoning effort 无效"};let K=z,j=G?.models.find((O)=>O.model===X&&(O.provider??"codex")===W);if(!j||!j.efforts.some((O)=>O.effort===K))return{ok:!1,message:`${i0(W)} · ${X}/${K} 不在选项中`};let _=$.tokenSource(j.sourceId);if(_?.modelCatalogState){if(!_.enabled||_.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${_.modelCatalogState.error??_.modelCatalogState.status}`};if(!_.models.some((O)=>O.model===X&&O.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let D=!!j.sourceId&&$.currentTokenSource()?.id!==j.sourceId,L=!$.processSourceMatches(_,X)||!!_?.modelEnvironmentRevision&&_.modelEnvironmentRevision($.currentModelLabel()??"")!==_.modelEnvironmentRevision(X),P=$.modelSelectionNeedsProcessStop(W,j.sourceId??$.selectedTokenSourceId,X,K);if($.currentProvider()===W&&!D&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!P&&!L)return $.modelPanels.delete(H),{ok:!0,message:`当前已是 ${i0(W)} · ${X} / ${K}`,card:M3({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 后再切换到 ${i0(W)}`};let A=$.currentModelLabel()!==X||D,M=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((L||P)&&$.proc?.isAlive()&&M)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(W==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&A&&M)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===W&&!D&&!L&&!P){let R=j.sourceId?$.tokenSource(j.sourceId)?.resolveSpawnModel(X)??X:X;if(W==="codex")await $.proc.setModelSettings(R,K);else return await rA($,$.proc,X,R,K,H,j.sourceId)}await $.applyModelSelectionUnlocked(W,X,K,j.sourceId);let O=OY($,W);return $.modelPanels.delete(H),{ok:!0,message:`已选择 ${i0(W)} · ${X} / ${K}`,card:M3({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:O})}}catch(O){let R=`模型切换失败: ${S(O)}`;return B(`session "${$.sessionName}": set model settings failed: ${S(O)}`),{ok:!1,message:R}}}var DY=20;var YB=N(()=>{_0();NY();X0();hJ();J1();_0();M$();G1();$0();h()});import{createHash as JN}from"node:crypto";function QN($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function v3($="default"){return HB(zB($))}function XB($="default"){return YN(zB($))}function zB($){return d0().map((Z)=>Z.forAccount?.($)??Z)}async function YN($){let Z=HB($),Q=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((H)=>H.tokenSourceId===V.id);if(X)return X;let z=await VN(V);return z===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:z}}))).filter((V)=>V!==null),Y=new Set(Q.map((V)=>V.tokenSourceId));return GB(Z.identities.filter((V)=>!Y.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Y.has(V.tokenSourceId)),...Q])}function VN($){return XN($)}async function XN($){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 HB($){let Z=[],J=[];for(let Q of $)zN(Q,Z,J);return GB(Z,J)}function GB($,Z){return{catalogGeneration:JN("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function zN($,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(HN($,Y,Q))}function HN($,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:QN($.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:VB($.defaultModel)===VB(Z.model),status:Q,...Y?{reason:Y}:{},spawnRevision:$.spawnRevision}}function VB($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var N6=N(()=>{h();X0()});import{randomUUID as GN}from"node:crypto";async function WB($,Z){if(!Z.trim()){await I($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}jB();let J=`agents_${GN()}`;y3.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()});let Q;if(!await i($.chatId,BB(J),(V)=>{Q=V}))await I($.chatId,`❌ agents 面板发送失败
253
- ${v(Q)}`)}function KB($,Z,J){let Q=BN($,J),Y=Number(Z);if(!Number.isInteger(Y))return jN("无效页码");let V=KN(Q.codexAccountId);return Q.page=Math.max(0,Math.min(V-1,Y)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:BB($)}}function BB($){let Z=y3.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=v3(Z.codexAccountId),Q=Math.max(1,Math.ceil(J.identities.length/R6));Z.page=Math.min(Z.page,Q-1);let Y=Z.page*R6;return dQ({panelId:$,page:Z.page,totalPages:Q,catalog:J.identities.slice(Y,Y+R6),failures:J.sourceFailures})}function KN($){return Math.max(1,Math.ceil(v3($).identities.length/R6))}function BN($,Z){jB();let J=y3.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function jN($){return{ok:!1,message:$,card:g1({title:"agents",message:$,ok:!1})}}function jB(){let $=Date.now()-WN;for(let[Z,J]of y3)if(J.createdAt<$)y3.delete(Z)}var R6=8,WN=1800000,y3;var _B=N(()=>{M$();$0();N6();y3=new Map});var EY={};r$(EY,{withTasklistLifecycleLock:()=>S6,tasklistNameForProject:()=>x6,reconcileTasklistDeletions:()=>qN,isTasklistAlreadyDeletedError:()=>PB,getTasklistBinding:()=>P1,enableTasklist:()=>RY,deleteTasklistRemoteIdempotently:()=>LB,deleteTasklist:()=>TY});import{existsSync as PN,readFileSync as LN}from"node:fs";function x6($){return`${$}[lodestar]`}function P1($){let Z=_1.get($);return Z?o4(Z):null}async function S6($,Z){let J=T6.get($)??Promise.resolve(),Q,Y=new Promise((X)=>{Q=X}),V=J.catch(()=>{}).then(()=>Y);T6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Q(),T6.get($)===V)T6.delete($)}}function PB($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function LB($,Z=kZ){try{return await Z($),"deleted"}catch(J){if(PB(J))return"already_deleted";throw J}}async function RY($,Z){return await S6($,async()=>{let J=P1($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=x6($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await CZ(Z),V=await bZ(Q,Y),X={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Y,createdAt:V.createdAt};return E6($,X),o4(X)})}async function TY($,Z){return await S6($,async()=>{let J=P1($);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},E6($,J);return await qB($,Z)})}async function qB($,Z){let J=P1($);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,E6($,J);try{if(await LB(Z)==="already_deleted")B(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(_1);return Y.delete($),DB(Y),_1.delete($),o4(J)}catch(Q){let Y=P1($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),E6($,Y);throw Q}}async function qN(){let $=[..._1.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await S6(J.projectName,()=>qB(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 DN(){if(!PN(u3))return;try{let $=JSON.parse(LN(u3,"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:FN(Q.deleting)};_1.set(Z,Y)}B(`tasklist: loaded ${_1.size} project bindings`)}catch($){B(`tasklist: load map failed: ${$}`)}}function FN($){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 E6($,Z){let J=new Map(_1);J.set($,o4(Z)),DB(J),_1.set($,o4(Z))}function DB($=_1){let Z={};for(let[J,Q]of $)Z[J]=o4(Q);a(u3,Z)}function o4($){return JSON.parse(JSON.stringify($))}var _1,T6;var xY=N(()=>{H0();$0();h();x0();_1=new Map,T6=new Map;DN()});function c1($,Z,J=!1){let Q=$.worktreeProjectName();return lQ({projectName:Q,tasklistName:x6(Q),binding:P1(Q),notice:Z,confirmDelete:J})}async function FB($){let Z;if(!await i($.chatId,c1($),(Q)=>{Z=Q}))await I($.chatId,`❌ task 面板发送失败
254
- ${v(Z)}`)}async function UB($){let Z=$.worktreeProjectName();try{let J=P1(Z),Q=await RY(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:c1($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${S(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${S(J)}`),{ok:!1,message:Q,card:c1($,{type:"error",content:`❌ ${Q}`})}}}function MB($,Z){let J=$.worktreeProjectName(),Q=P1(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:c1($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:c1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:c1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function OB($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let V=`已删除 ${(await TY(J,Q)).name}`;return{ok:!0,message:V,card:c1($,{type:"success",content:`✅ ${V}`})}}catch(Y){let V=`删除失败: ${S(Y)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${S(Y)}`),{ok:!1,message:V,card:c1($,{type:"error",content:`❌ ${V}`})}}}var AB=N(()=>{M$();$0();h();xY()});import{open as MN}from"node:fs/promises";import{basename as ON}from"node:path";function SY($){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 L1($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class NB{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:V0,getToken:m$,retry:s1,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(),z=Q?.(),H=z instanceof FormData,G=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(G>0)await this.deps.wait(G);Y?.throwIfAborted(),this.lastStartedAt=Date.now();let W=AbortSignal.timeout(RN),K=new AbortController,j=()=>K.abort(W.reason),_=()=>K.abort(Y.reason);W.addEventListener("abort",j,{once:!0}),Y?.addEventListener("abort",_,{once:!0});let D=K.signal;try{let L=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!H&&z!==void 0?{"Content-Type":"application/json"}:{}},...z!==void 0?{body:H?z:JSON.stringify(z)}:{},signal:D});return(await B$(L,$)).data}catch(L){if(D.aborted&&D.reason?.name==="TimeoutError")throw D.reason;throw L}finally{W.removeEventListener("abort",j),Y?.removeEventListener("abort",_)}}));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:L1(J?.token,"交付文件夹"),url:SY(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return L1(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Q=L1(J?.token,"群文件夹");if(Q!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Q,url:SY($.url),name:L1(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 y0&&Y.code===99991672)Y.message=`同步群文件夹名称需要应用身份权限 drive:file:upload;${Y.message}`;throw Y}let Q=await this.getFolder($,J);if(Q.name!==Z)throw Error("群文件夹名称更新未生效");return Q}async grantFolderAccess($,Z,J,Q){L1(Z,"交付群"),L1(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,z,H]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((W)=>W.member_type===X&&W.member_id===z)?.perm!==H)throw Error(`交付文件夹权限未生效:${X} / ${H}`)}async closeFileLinkSharing($,Z){L1($,"交付文件");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 MN($,"r");try{let V=await Y.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=ON($),z={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},H;if(V.size<=AN){let L=await Y.readFile(),P=await Y.stat();if(L.length!==V.size||P.mtimeMs!==V.mtimeMs||P.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");H=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let F=new FormData;for(let[U,A]of Object.entries(z))F.append(U,String(A));return F.append("file",new Blob([Uint8Array.from(L)]),X),F},Q)}else{let L=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>z,Q),P=L1(L?.upload_id,"分片上传事务"),F=L?.block_size,U=L?.block_num;if(!Number.isSafeInteger(F)||F<=0||F>NN||!Number.isSafeInteger(U)||U!==Math.ceil(V.size/F))throw Error("云空间返回的分片策略无效");for(let M=0;M<U;M++){Q?.throwIfAborted();let O=Math.min(F,V.size-M*F),R=Buffer.alloc(O),w=0;while(w<O){let T=await Y.read(R,w,O-w,M*F+w);if(!T.bytesRead)throw Error("交付文件在分片读取时发生变化");w+=T.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let T=new FormData;return T.append("upload_id",P),T.append("seq",String(M)),T.append("size",String(O)),T.append("file",new Blob([Uint8Array.from(R)]),X),T},Q)}let A=await Y.stat();if(A.size!==V.size||A.mtimeMs!==V.mtimeMs||A.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");H=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:P,block_num:U}),Q)}let G=L1(H?.file_token,"已上传文件"),W={token:G,url:"",name:X,bytes:V.size},K=[];try{J(W)}catch(L){K.push(L)}try{await this.closeFileLinkSharing(G)}catch(L){K.push(L)}if(K.length===1)throw K[0];if(K.length>1)throw AggregateError(K,K.map((L)=>L instanceof Error?L.message:String(L)).join(";"));Q?.throwIfAborted();let j=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:G,doc_type:"file"}],with_url:!0}),Q),_=j?.metas?.find((L)=>L.doc_token===G&&L.doc_type==="file");if(j?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let D={...W,url:SY(_.url)};return J(D),D}finally{await Y.close()}}}var AN=20971520,NN=20971520,RN=60000,h2;var RB=N(()=>{p0();$0();o2();h2=new NB});import{randomUUID as TB}from"node:crypto";import{basename as TN}from"node:path";class CY{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:TB(),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:TB(),path:$,name:TN($),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}
255
- ${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{let Z;if($=await this.deps.sendCard(this.snapshot,(J)=>{Z=J}),!$)throw Error(`飞书未返回交付卡消息 ID:${v(Z)}`)}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?`
256
- 已上传文件所在文件夹:${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 EB=()=>{};class bY{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=Q$(Z),Q=this.load(),Y=Q.workspaces[J]?.enabled;if(Y===void 0){let X=new Set(this.legacyChats($,J).map((z)=>Q.groups[z].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=Q$(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=Q$(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)||!f3(Z.groups)||Z.version===2&&!f3(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Y,V]of Object.entries(Z.workspaces??{})){if(!f3(V)||typeof V.enabled!=="boolean"||Q$(Y)!==Y)throw Error("工作目录文件交付开关无效");J.workspaces[Y]={enabled:V.enabled}}for(let[Y,V]of Object.entries(Z.groups)){if(!Y||!f3(V))throw Error("群文件夹绑定无效");let X=Z.version===1?V.enabled:V.legacyEnabled;if((Z.version===1||X!==void 0)&&typeof X!=="boolean")throw Error("群文件交付开关无效");if(X&&!V.folder)throw Error("已启用的旧群缺少文件夹绑定");if(V.folder!==void 0)EN(V.folder);J.groups[Y]={...V.folder?{folder:structuredClone(V.folder)}:{},...X===void 0?{}:{legacyEnabled:X}}}let Q=new Map;for(let[Y,V]of Object.entries(J.groups)){if(!V.folder)continue;let X=Q.get(V.folder.token);if(X!==void 0)throw Error(`云空间文件夹重复绑定到多个群:${X} / ${Y}`);Q.set(V.folder.token,Y)}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&&Q$(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){for(let[Q,Y]of Object.entries(this.load().groups))if(Q!==$&&Y.folder?.token===Z.token)throw Error("云空间文件夹已绑定其他群,不能共用交付目录");let J=structuredClone(this.load());J.groups[$]={...J.groups[$],folder:Z},this.commit(J)}commit($){this.deps.write($),this.state=$}}function f3($){return!!$&&typeof $==="object"&&!Array.isArray($)}function EN($){if(!f3($)||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 xB=N(()=>{U4()});import{join as xN}from"node:path";import{readFileSync as SN}from"node:fs";function SB($){return new CY($,{resolveFolder:(Z,J)=>s4.resolveFolder(Z,J),uploadFile:(Z,J,Q,Y)=>h2.uploadFile(Z,J,Q,Y),sendCard:(Z,J)=>i($.chatId,QQ(Z),J),persist:(Z)=>a(xN(DV,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await k($.chatId,Z))throw Error(Z)}})}var s4;var CB=N(()=>{$0();RB();EB();h7();H0();x0();h();xB();U4();s4=new bY({read:()=>{try{return SN(Y5,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>a(Y5,$),workDirForChat:($)=>{let Z=[...P0].filter(([,Y])=>Y===$).map(([Y])=>Y),J=L0.get($);if(!Z.length&&J)Z.push(J);let Q=new Set(Z.map((Y)=>Q$(O4(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 bB($,Z,J,Q,Y,V){let X,z="",H="";try{switch(Q.trim().toLowerCase()){case"":case"status":X=Y.get($);break;case"on":X=await Y.enable($,J),z="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Y.disable($),z="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(K){H=K instanceof Error?K.message:String(K);try{X=Y.get($)}catch{X=void 0}}let G=YQ({groupName:Z,workDir:V,settings:X,notice:z,error:H}),W;if(!await Y.sendCard(G,(K)=>{W=K}))await Y.reportError(`❌ 文件交付设置卡发送失败:${v(W)}${H?`
257
- 设置失败:${H}`:""}`)}var kB=N(()=>{h7()});function wB($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
258
- `)}function vB($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",wB(Z),"- 文件交付约定由 Lodestar 按工作目录设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写工作目录配置。"}`,J[$],...CN].join(`
259
- `)}function yB($){return`[Lodestar 文件交付约定更新]
244
+ `),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 VY($,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)g0(Q,Y);X$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var MK=R(()=>{$0();h();FK()});import{mkdtemp as MA,rm as OA,writeFile as AA}from"node:fs/promises";import{createRequire as NA}from"node:module";import{tmpdir as RA}from"node:os";import{join as OK}from"node:path";function wA($){let Z=TK.get($);if(Z)return Z;let{liteAdaptor:J}=f2("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Q}=f2("mathjax-full/js/handlers/html.js"),{mathjax:Y}=f2("mathjax-full/js/mathjax.js"),{TeX:V}=f2("mathjax-full/js/input/tex.js"),{AllPackages:X}=f2("mathjax-full/js/input/tex/AllPackages.js"),{SVG:z}=f2("mathjax-full/js/output/svg.js"),H=J({fontSize:$});Q(H);let G=Y.document("",{InputJax:new V({packages:X}),OutputJax:new z({fontCache:"none"})}),W={adaptor:H,doc:G};return TK.set($,W),W}function EK($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function vA($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function yA($,Z=HY,J=!0){try{let Q=Z*TA,{adaptor:Y,doc:V}=wA(Z),X=V.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),z=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(z)){let p=z.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(p)}let H=z.indexOf("<svg"),G=z.lastIndexOf("</svg>");if(H<0||G<0)throw Error("MathJax returned no SVG");let W=z.slice(H,G+6),K=W.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let j=EK(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),_=EK(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),D=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!D)throw Error("MathJax SVG missing viewBox");let P=D.trim().split(/[\s,]+/).map(Number);if(P.length!==4||P.some((p)=>!Number.isFinite(p))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[L,F,U,A]=P,M=/<text\b/.test(W)?bA:0,O=`${L} ${F} ${U+M} ${A}`,T=j*Q,k=M*(T/U),E=Math.max(1,Math.ceil(T+k)),f=Math.max(1,Math.ceil(_*Q)),d=EA-XY*2,S=Math.min(1,d/E),g=Math.max(1,Math.round(E*S)),V0=Math.max(1,Math.round(f*S));if(S<1&&V0<xA)throw Error(`formula would be unreadable after width cap (${g}x${V0})`);let e=g+XY*2,c=V0+NK*2,N=W.slice(K.length,-6).replace(/currentColor/g,AK).replace(/font-family="serif"/g,`font-family="${kA}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${c}" viewBox="0 0 ${e} ${c}" style="color:${AK}">`,`<rect x="0" y="0" width="${e}" height="${c}" rx="6" fill="${bK}"/>`,`<svg x="${XY}" y="${NK}" width="${g}" height="${V0}" viewBox="${vA(O)}" preserveAspectRatio="xMidYMid meet">`,N,"</svg>","</svg>"].join(""),width:e,height:c}}catch(Q){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function fA($,Z=HY,J=!0){let Q=yA($,Z,J);if(!Q)return null;try{let{Resvg:Y}=f2("@resvg/resvg-js"),X=new Y(Q.svg,{background:bK,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:RK,sansSerifFamily:RK}}).render().asPng(),z=new DataView(X.buffer,X.byteOffset,X.byteLength),H=z.getUint32(16),G=z.getUint32(20);if(H!==Q.width||G!==Q.height)throw Error(`PNG dimensions ${H}x${G} != SVG ${Q.width}x${Q.height}`);return{png:X,width:H,height:G}}catch(Y){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function hA($){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 xK($,Z){let J=[],Q=(W,K,j)=>{let _=W[0],D=K.trim();if(!D)return;J.push({start:Z+W.index,end:Z+W.index+_.length,tex:D,raw:_,display:j})},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 z=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=z.exec($))!==null){let W=(Y[1]??"").trim();if(hA(W))Q(Y,W,!1)}J.sort((W,K)=>W.start-K.start||K.end-W.end);let H=[],G=-1;for(let W of J){if(W.start<G)continue;H.push(W),G=W.end}return H}function kK($){let Z=xZ($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...xK($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...xK($.slice(Q),Q));return J}function IA($){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(SK[Q])return SK[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 cA($){let Z=CK.get($);if(Z!==void 0)return Z;return Z=mA++,CK.set($,Z),Z}function lA($,Z){return`${CA}\x00${cA(Z)}\x00${$}`}function uA($){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 dA($,Z){let J=lA($,Z),Q=y2.get(J);if(Q)return Q;let Y=zY.get(J);if(Y)return Y;let V=(async()=>{let X=fA($,HY,!0);if(!X)return null;let z=null;try{z=await MA(OK(RA(),"lodestar-math-"));let H=OK(z,`formula-${uA($)}.png`);await AA(H,X.png);let G=await Z(H,{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(y2.has(J))y2.delete(J);y2.set(J,W);while(y2.size>pA){let K=y2.keys().next().value;if(typeof K!=="string")break;y2.delete(K)}return W}catch(H){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${H}`),null}finally{if(z)try{await OA(z,{recursive:!0,force:!0})}catch(H){B(`math-render: temp cleanup failed for ${z}: ${H}`)}}})();zY.set(J,V);try{return await V}finally{zY.delete(J)}}function iA($,Z,J){let Q=$.width<=SA;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 wK($,Z={}){let J=kK($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??gA,Y=await Promise.all(J.map(async(W)=>{if(!W.display){let K=IA(W.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await dA(W.tex,Q)}})),V=[],X="",z=0,H=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],j=Y[W];if(X+=$.slice(z,K.start),j.unicode!==null){X+=j.unicode,z=K.end;continue}let _=j.uploaded;if(!_){X+=K.raw,z=K.end;continue}G(),V.push(iA(_,K,H++)),z=K.end}if(X+=$.slice(z),G(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:H}}function GY($){return kK($).length>0}var f2,TA=0.5,HY=22,AK="#1F2329",bK="#F7F8FA",XY=12,NK=8,EA=720,xA=14,SA=278,CA="v4-native-cjk-tail-pad",bA=1100,RK,kA="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",TK,SK,gA=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => ($0(),Z0));return Z($)},CK,mA=1,y2,zY,pA=512;var vK=R(()=>{h();f2=NA(import.meta.url),RK=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",TK=new Map;SK={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:"Ω"};CK=new WeakMap,y2=new Map,zY=new Map});import{readFileSync as aA}from"node:fs";function i4($){return WY.has($)}function C3($){WY.add($)}function b3($){WY.delete($)}function p1(){try{let $={};for(let[Z,J]of m0)$[Z]=J;a(S3,$)}catch($){throw B(`notify-callbacks: save failed (${S3}): ${$}`),$}}function IK(){let $=[],Z;try{Z=aA(S3,"utf8")}catch(J){if(J?.code==="ENOENT")return[];throw B(`notify-callbacks: read failed (${S3}): ${J}`),J}try{let J=JSON.parse(Z);if(!J||typeof J!=="object"||Array.isArray(J))throw Error("notify callback store must be an object");let Q=Date.now()-hK,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(X.dispatchState&&!X.resolvedAt&&!X.unknownAt)X.unknownAt=Date.now(),X.unknownBy={buttonId:X.dispatchState.buttonId,openId:X.dispatchState.openId},X.unknownReason="服务在按钮回调期间中断,无法确认是否送达,禁止自动重试",V++;if(m0.set(X.notifyId,X),(X.replyState?.status==="sending"||X.dispatchState)&&X.unknownAt)$.push(X)}if(B(`notify-callbacks: loaded ${m0.size} registration(s)${Y?`, dropped ${Y} stale`:""}`),V)B(`notify-callbacks: ${V} interrupted callback(s) marked UNKNOWN`);if(Y>0||V>0)p1()}catch(J){throw B(`notify-callbacks: load failed (${S3}): ${J}`),J}return $}function gK($){let Z=Date.now();if(Z-fK>=oA)sA(Z),fK=Z;m0.set($.notifyId,$),p1()}function j1($){return m0.get($)}function mK($,Z,J){let Q=m0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);if(Q.resolvedAt||Q.unknownAt||Q.dispatchState)throw Error("notify callback is already dispatched or finalized");Q.dispatchState={buttonId:Z,openId:J,startedAt:Date.now()};try{p1()}catch(Y){throw delete Q.dispatchState,Y}}function pK($){let Z=m0.get($);if(!Z?.dispatchState)throw Error(`notify callback is not dispatching: ${$}`);let J=Z.dispatchState;delete Z.dispatchState;try{return p1(),{state:"retry"}}catch(Q){Z.dispatchState=J;let Y=`callback failure persistence failed: ${Q instanceof Error?Q.message:Q}`;try{D6($,J.buttonId,J.openId,Y)}catch(V){Z.unknownReason=`${Y}; unknown tombstone persistence also failed: ${V instanceof Error?V.message:V}`}return{state:"unknown",detail:Z.unknownReason??Y}}}function KY($){return[...m0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function k3($,Z){if(!$)return;return KY($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function cK($,Z){return!!Z&&[...m0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function n4($,Z){let J=m0.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{p1()}catch(V){if(Q)J.replyState=Q;else delete J.replyState;if(Y)J.replyMessageIds=Y;else delete J.replyMessageIds;throw V}}function w3($,Z,J){let Q=m0.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,dispatchState:Q.dispatchState};Q.resolvedAt=Date.now(),Q.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Q.unknownAt,delete Q.unknownBy,delete Q.unknownReason,delete Q.dispatchState;try{p1()}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;if(Y.dispatchState!==void 0)Q.dispatchState=Y.dispatchState;throw V}}function D6($,Z,J,Q){let Y=m0.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,p1()}function F6($,Z,J){try{return w3($,Z,J),{state:"complete"}}catch(Q){let V=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{D6($,Z,J,V)}catch(X){let z=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${z}`;let H=m0.get($);if(H)H.unknownReason=V}return{state:"unknown",detail:V}}}function sA($=Date.now()){let Z=$-hK,J=0;for(let[Q,Y]of m0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)m0.delete(Q),J++;if(J>0)p1();return J}async function BY($,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(),yK);try{let X=await bV($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let H;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())H=K.trim().slice(0,500)}else if(G)H=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:H}}let z="";try{z=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${z?` ${z}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${yK}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function lK($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((z)=>z.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 hK=604800000,yK=2500,m0,fK,oA=86400000,WY,S3;var v3=R(()=>{p0();h();H0();x0();m0=new Map,fK=Date.now(),WY=new Set;S3=FV});function U6($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function a4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(k3($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(U6($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function jY($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Q=J.currentIdx===void 0?void 0:k3($.chatId)?"notification":U6($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Q}}function _Y($,Z){let J=$.pendingAsks.get(Z),Q=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||a4($,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,z=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(a0(Q.cardId),await E7(Q.cardId,{config:{summary:{content:z}}}),$.currentTurn!==Q||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Y||J.currentIdx===void 0||a4($,Z))return;await q2(Q.messageId,[Q.userOpenId])})().catch((H)=>B(`session "${$.sessionName}": question notification failed: ${H}`))}function M6($){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=jY($,J);if(V.waitingFor)Q.announced=!1,Q.announcementVersion=(Q.announcementVersion??0)+1;F0(Z.cardId,C.tool(Y.i),l4(Y.i,J,Q.questions,"\uD83E\uDD14",V)),_Y($,J)}}function uK($){return U6($)!==void 0}async function dK($,Z,J,Q){let Y=U6($);if(!Y){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Q);return}let[V,X]=Y,z=a4($,V);if(z){let G=`${z}。这条文字未提交,请稍后重新发送。`,W;if(!await b($.chatId,G,(K)=>{W=K}))throw Error(`提问等待提示发送失败: ${G}
245
+ ${w(W)}`);return}if(await LY($,V,X.currentIdx,Z,J)&&Q)X$(Q,"CheckMark")}async function iK($,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 nK($,Z,{optionIdx:Q,user:Y})}async function LY($,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 nK($,Z,{customText:X,user:Y})}function nK($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=a4($,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 z;if(J.customText!==void 0)z=J.customText;else if(J.optionIdx!==void 0){let j=X.options?.[J.optionIdx];if(!j)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;z=j.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[X.question]=z,Q.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let H=Q.questions.length,G=void 0;for(let j=V+1;j<H;j++)if(!Q.answered.has(j)){G=j;break}Q.currentIdx=G;let W=$.currentTurn,K=W?.toolByUseId.get(Z);if(W&&K){let j=l4(K.i,Z,Q.questions,G===void 0?"✅":"\uD83E\uDD14",{currentIdx:G,answered:Q.answered});F0(W.cardId,C.tool(K.i),j)}if(G===void 0)if(Q.requestId)PY($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),M6($);return!0}function PY($,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),M6($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var O6=R(()=>{G1();M$();$0();h();v3()});import{isAbsolute as rA}from"node:path";function w0($){if($?.planLiveInserted)return C.planLive;return $?.taskLiveInserted?C.taskBoardLive:C.footer}function eA($){return $==="ImageGeneration"||$==="imageGeneration"}function $N($,Z,J){if(J||!eA($))return null;let Q=q6(Z.trim());return rA(Q)?Q:null}function ZN($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function aK($,Z,J){return $==="read"?q3(Z,J):P3(Z,J)}function oK($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=ZN(J);if(Y&&$.currentTurn.openBatchI!==null){let H=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(H);if(G&&G.kind===Y){let W=G.items.length;G.items.push({toolUseId:Z,input:Q,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Q,batchSlot:W});let K=Y==="read"?q3(H,G.items):P3(H,G.items);F0($.currentTurn.cardId,C.tool(H),K),A6($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let V=w2(J);if(V){let H=$.currentTurn;if(V==="TaskCreate"&&!H.taskBoardResetThisTurn)$.taskBoard=[],H.taskBoardResetThisTurn=!0;if(!H.taskLiveInserted)H.taskLiveInserted=!0,T0(H.cardId,v2($.taskBoard),{type:"insert_before",targetElementId:C.footer});else B0(H.cardId,C.taskBoardLive,v2($.taskBoard),{notifyCardFailure:!1});let G=V==="TaskCreate";if(G)H.taskUpdateI=null;else H.taskCreateI=null;let W=(G?H.taskCreateI:H.taskUpdateI)===null;if(W)if(G)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let K=G?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(Z,{i:K,name:J,input:Q});let j=m1(K,$.taskBoard,{name:V,status:"⏳"});W?T0(H.cardId,j,{type:"insert_before",targetElementId:w0(H)}):F0(H.cardId,C.tool(K),j),A6(H,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let H=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:H}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let G=Y==="read"?q3(X,H):P3(X,H);T0($.currentTurn.cardId,G,{type:"insert_before",targetElementId:w0($.currentTurn)},void 0,"capacity"),A6($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let H=Array.isArray(Q?.questions)?Q.questions:[],G=H.length>0?0:void 0,W=new Map;$.pendingAsks.set(Z,{questions:H,i:X,answers:{},answered:W,currentIdx:G});let K=l4(X,Z,H,"\uD83E\uDD14",jY($,Z));T0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:w0($.currentTurn)}),_Y($,Z);return}let z=a$(X,J,Q,null,"⏳");T0($.currentTurn.cardId,z,{type:"insert_before",targetElementId:w0($.currentTurn)},void 0,"capacity"),A6($.currentTurn,J,Q)}function A6($,Z,J){if(!$)return;let Q=y1(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,V=S2(Z),X=Y?`\uD83D\uDD27 ${V}: ${Y}`:`\uD83D\uDD27 ${V}`;h4($.cardId,X)}function sK($,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(([,W])=>W!==void 0))};let X=typeof J==="string"?J:Array.isArray(J)?J.map((W)=>W?.text??JSON.stringify(W)).join(`
246
+ `):JSON.stringify(J);if(V.output=X,V.isError=Q,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let z=$N(V.name,X,Q);if(z){JN($,$.currentTurn,V,z),h2($);return}if(V.name==="AskUserQuestion"){h2($);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=Q;let j=aK(W.kind,V.i,W.items);F0($.currentTurn.cardId,C.tool(V.i),j)}h2($);return}let H=w2(V.name);if(H){QN($,V,H,V.input,X,Q,V.resolvedNote);return}let G=a$(V.i,V.name,V.input,X,Q?"❌":"✅",V.resolvedNote);F0($.currentTurn.cardId,C.tool(V.i),G),h2($)}function JN($,Z,J,Q){if(Z.outboundSeenPaths.has(Q))return;Z.outboundSeenPaths.add(Q);let Y=Z.cardId,V=C.tool(J.i),X=Z.imageDeliveryInflight??=new Map,z=X.get(Y)??new Set;X.set(Y,z);let H=[],G=(async()=>{let W=null;try{W=await zJ(Q,(P)=>{H.push(`图片上传:${w(P)}`)})}catch(P){H.push(`图片上传:${w(P)}`),B(`generated image upload failed: ${P}`)}if(W){let P=!1;try{P=await B0(Y,V,a$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1,onFailure:(L)=>{H.push(`图片嵌入:${w(L)}`)}})}catch(L){H.push(`图片嵌入:${w(L)}`),B(`generated image embed failed: ${L}`)}if(P){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 K,j=W?await z7($.chatId,W,(P)=>{K=P})!==null:await u9($.chatId,Q);if(j)Z.outboundSentPaths.add(Q);else B(`generated image delivery failed: ${Q}`);if(!j&&W)H.push(`图片发送:${w(K)}`);J.resolvedNote=[j?"图片已单独发送。":"图片发送失败。",...H].join(`
247
+ `);let _,D=!1;try{D=await B0(Y,V,a$(J.i,J.name,J.input,J.output??null,j?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1,onFailure:(P)=>{_=P}})}catch(P){_=P}if(!D)B(`generated image status write failed card=${Y} path=${Q}: ${w(_)}
248
+ ${J.resolvedNote}`);if(!j&&W)await b($.chatId,`❌ 生成图片发送失败:${H.join(`
249
+ `)}`)})().catch(async(W)=>{B(`generated image delivery failed: ${W}`),await b($.chatId,`❌ 生成图片发送失败:${[...new Set([...H,w(W)])].join(`
250
+ `)}`)});z.add(G),G.finally(()=>{if(z.delete(G),!z.size)X.delete(Y)}).catch((W)=>B(`generated image failure notice failed: ${W}`))}async function qY($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Q)=>[...Q]);await Promise.allSettled(J)}function QN($,Z,J,Q,Y,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=sQ($.taskBoard,J,Q,Y);let z=m1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(F0($.currentTurn.cardId,C.tool(Z.i),z),$.currentTurn.taskLiveInserted)B0($.currentTurn.cardId,C.taskBoardLive,v2($.taskBoard),{notifyCardFailure:!1});h2($)}function h2($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function DY($,Z,J,Q,Y,V=$.currentTurn){let X=V;if(!X)return;for(let[z,H]of Q){if(X.toolByUseId.has(z))continue;let G=H.batchSlot??null,W=H.input,K,j;if(G!=null){let U=Y.get(H.i)?.items[G];if(!U)continue;W=U.input,K=U.output,j=U.isError}else K=H.output??null,j=H.isError??!1;let _=K!=null,D=y4(Z,C.tool(H.i));if(_&&!D)continue;if(G!=null){let U=Y.get(H.i)?.kind;if(!U)continue;let A=X.toolCount++,M={toolUseId:z,input:W,output:K,isError:j};X.toolBatches.set(A,{kind:U,items:[M]}),X.toolByUseId.set(z,{...H,i:A,batchSlot:0}),T0(J,aK(U,A,[M]),{type:"insert_before",targetElementId:w0(X)});continue}let P=w2(H.name);if(P){let U=P==="TaskCreate";if(U)X.taskUpdateI=null;else X.taskCreateI=null;let A=(U?X.taskCreateI:X.taskUpdateI)===null;if(A)if(U)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let M=U?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(z,{...H,i:M});let O=!_?"⏳":j?"❌":"✅",T=m1(M,$.taskBoard,{name:P,status:O},H.resolvedNote);A?T0(J,T,{type:"insert_before",targetElementId:w0(X)}):F0(J,C.tool(M),T);continue}let L=X.toolCount++;X.toolByUseId.set(z,{...H,i:L});let F=!_?"⏳":j?"❌":"✅";T0(J,a$(L,H.name,H.input,K,F,H.resolvedNote,H.imageKey),{type:"insert_before",targetElementId:w0(X)})}}var tK=R(()=>{QY();G1();M$();$0();h();O6()});async function rK($,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(G){return B(`session "${$.sessionName}": permission response ${Z} failed: ${G}`),{ok:!1,message:`权限决定发送失败: ${G instanceof Error?G.message:G}`}}$.pendingPermissions.delete(Z);let z=$.currentTurn,H=z?.toolByUseId.get(Y.toolUseId);if(z&&H){let G=w2(H.name);if(J==="deny"){let W=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,K=G?m1(H.i,$.taskBoard,{name:G,status:"❌"},W):a$(H.i,H.name,H.input,W,"❌");F0(z.cardId,C.tool(H.i),K)}else{let W=J==="allow_always"?"始终允许":"已允许";H.resolvedNote=`✅ **${W}** by ${Q||"匿名"}`;let K=G?m1(H.i,$.taskBoard,{name:G,status:"⏳"},H.resolvedNote):a$(H.i,H.name,H.input,null,"⏳",H.resolvedNote);F0(z.cardId,C.tool(H.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 eK($,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)PY($,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=RQ(Y.i,Y.name,Y.input,Z.request_id);if(F0(J.cardId,C.tool(Y.i),V),J.userOpenId&&J.messageId){let X=y1(Y.name,Y.input),z=S2(Y.name),H=X&&X.length>30?X.slice(0,30)+"…":X,G=H?`\uD83D\uDD10 等审批: ${z} · ${H}`:`\uD83D\uDD10 等审批: ${z}`;(async()=>{a0(J.cardId),await E7(J.cardId,{config:{summary:{content:G}}}),await q2(J.messageId,[J.userOpenId])})()}}var $B=R(()=>{G1();M$();$0();h();O6()});function zN($){let Z=!1,J=()=>{},Q=()=>{},Y=$.sessionId,V=()=>{$.off("context_compacted",H),$.off("exit",G),$.off("error",W)},X=(j)=>{if(Z)return;Z=!0,V(),J(j)},z=(j)=>{if(Z)return;Z=!0,V(),Q(j)},H=(j)=>{if(j.phase==="start")return;if(j.threadId&&Y&&j.threadId!==Y)return;X(j)},G=()=>z(Error(`${$.provider} process exited before context compaction completed`)),W=(j)=>z(j instanceof Error?j:Error(String(j))),K=new Promise((j,_)=>{J=j,Q=_});return $.on("context_compacted",H),$.once("exit",G),$.once("error",W),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function HN($,Z){let J=[],Q=new Set,Y=(z,H)=>{let G=H.threadId??Z;if(G&&z.threadId&&z.threadId!==G)return!1;if(H.turnId)return z.turnId===H.turnId;return!0},V=(z)=>{for(let H=J.length-1;H>=0;H--){let G=J[H];if(G&&Y(G,z))return G}return null},X=(z)=>{if(Z&&z.threadId&&z.threadId!==Z)return;let H={usage:z.usage,contextWindow:z.contextWindow,threadId:z.threadId,turnId:z.turnId};J.push(H);for(let G of[...Q])if(Y(H,G.notice))G.finish(H)};return $.on("token_usage",X),{waitFor(z,H){let G=V(z);if(G)return Promise.resolve(G);return new Promise((W)=>{let K=null,j={notice:z,finish:(_)=>{if(K)clearTimeout(K);Q.delete(j),W(_)}};K=setTimeout(()=>j.finish(null),H),Q.add(j)})},cancel(){$.off("token_usage",X);for(let z of[...Q])z.finish(null)}}}function GN($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=g7($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=m7($.contextWindow);return` · \uD83E\uDDE0 ${JW(Z,J)} (${p7(Z,J)})`}async function ZB($){$.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 b($.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 b($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let G=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(G)await $.closeStatusCard(G,"⏳ 上下文压缩已在进行中");else await b($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Q=J.sessionId?S0(J.sessionId):"",Y=$.withModel(Q?`\uD83E\uDDE0 压缩上下文 thread=${Q}`:"\uD83E\uDDE0 压缩上下文…"),V=await $.openStatusCard("compact",Y,"orange"),X=async(G)=>{if(V)await $.closeStatusCard(V,G);else await b($.chatId,G)},z=zN(J),H=HN(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let G=await z.promise,W=await H.waitFor(G,XN),K=G.threadId?` thread=${S0(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${GN(W)}`))}catch(G){if(z.cancel(),G instanceof K2)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${x(G)}`)}finally{H.cancel(),$.manualContextCompactionPending=!1}}var XN=1500;var JB=R(()=>{_0();$0()});import{randomUUID as KN}from"node:crypto";function QB($,Z){return{ok:!1,message:Z,card:H6($.sessionName,!1,Z)}}async function UY($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return QB($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${x(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof K4&&J.error.confirmedModel!==null?Z.model:null,Z.confirmedEffort=J.ok?Z.effort:null;let Q=J.ok?null:x(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=`模型和思考档位已应用,但保存选择失败:${x(Y)}`}if(Q!==null)return Z.phase="failed",Z.error=`${Q}。本次完整设置未保存,后续输入暂停;请重新发送 md 完成选择,或 restart 恢复已保存的设置。`,B(`session "${$.sessionName}": model settings incomplete: ${Z.error}`),QB($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${i0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:O3({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:AY($,Z.provider)})}}async function BN($,Z,J,Q,Y,V,X){let z,H=new Promise((D)=>{z=D}),G={proc:Z,provider:Z.provider,model:J,effort:Y,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(D){G.cancelled=D,z({ok:!1,error:Error(D)})}};$.modelSettingsChange=G;let W=Promise.resolve().then(()=>Z.setModelSettings(Q,Y)).then(()=>({ok:!0}),(D)=>({ok:!1,error:D})),K=Promise.race([W,H]),j=Symbol("model-settings-pending"),_;try{let D=await Promise.race([K,new Promise((L)=>{_=setTimeout(()=>L(j),20000)})]);if(D!==j)return await UY($,G,D);let P=`正在等待 ${i0(Z.provider)} 确认 ${J} / ${Y},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:P,card:H6($.sessionName,!0,P),completion:K.then((L)=>$.finishModelSettingsChange(G,L))}}finally{clearTimeout(_)}}function jN($){let Z=$.currentTokenSource();return d0().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 MY($,Z,J=Z.models){let Q=$.currentModelLabel(),Y=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let z=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:z,efforts:X.efforts.map((H)=>({effort:H,description:H==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:H===X.defaultEffort,selected:z&&Y===H}))}})}async function YB($){let Z=KN(),J=jN($);$.modelPanels.set(Z,{models:[]});let Q,Y=await n($.chatId,CQ({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}),(V)=>{Q=V});if(!Y)$.modelPanels.delete(Z),await I($.chatId,`❌ 模型面板发送失败:${w(Q)}`);else{let V=$.modelPanels.get(Z);if(V)V.messageId=Y}}async function OY($,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??"刷新失败"}`};if(Y.modelCatalogState?.status==="idle"||Y.modelCatalogState?.status==="loading")return{ok:!1,message:"模型目录缓存尚未就绪,后台刷新中"};let X=MY($,Y),z=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Q,messageId:z,mode:"select",editable:!!Y.modelSelection,sourceRevision:Y.spawnRevision}),N6($,V,Q,0)}async function N6($,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/FY));if(!Number.isInteger(Q)||Q<0||Q>=V)return{ok:!1,message:"模型页码无效"};return Y.models=Y.catalog.slice(Q*FY,(Q+1)*FY),Y.page=Q,Y.totalPages=V,{ok:!0,message:"",card:bQ({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 VB($,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:MY($,Y,V),sourceId:J,messageId:Q.messageId,mode:"add",editable:!0,sourceRevision:Y.spawnRevision}),N6($,Z,J,0)}async function XB($,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((z)=>z.model===Q))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Y==="delete"){let z=[...S$.all].filter((H)=>H.currentTokenSource()?.id===J&&H.currentModelLabel()===Q.replace(/\[1m\]$/,""));if(z.length)return{ok:!1,message:`补录模型仍被会话 ${z.map((H)=>H.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Y==="delete")await IG(J,Q,$.codexAccountId());else await fG(J,Q,Y,$.codexAccountId());for(let H of S$.all)for(let[G,W]of H.modelPanels)if(W.sourceId===J&&(H!==$||G!==Z))H.modelPanels.delete(G);return{...await OY($,J,Z),message:Y==="add"?"模型已显示":Y==="delete"?"补录模型已删除":"模型已隐藏"}}catch(z){return{ok:!1,message:`模型列表更新失败:${x(z)}`}}}async function zB($,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:wQ($.sessionName,Y.display,V)}}async function HB($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),V=$.tokenSource(Q.sourceId),X=[],z=async(_)=>{if(!Q.cardMessageId)return!1;let D="",P=!1,L=!1;try{D=await l$(Q.cardMessageId),E$(D,1);let F;if(P=await B0(D,C.modelPanel,_,{notifyCardFailure:!1,onFailure:(A)=>{F=A}}),!P)throw Error(`model panel replace rejected: ${w(F)}`);let U;if(L=await k0(D,{config:{streaming_mode:!1}},(A)=>{U=A}),!L)throw Error(`model panel streaming-off rejected: ${w(U)}`)}catch(F){B(`model-custom: card update MISS (${F?.message??F})`),X.push(x(F))}finally{if(D){if(!L)try{let F;if(L=await k0(D,{config:{streaming_mode:!1}},(U)=>{F=U}),!L)X.push(`model panel streaming-off rejected: ${w(F)}`)}catch(F){B(`model-custom: streaming-off retry MISS (${F?.message??F})`),X.push(w(F))}if(P&&L)try{await q$(D)}catch(F){B(`model-custom: card dispose MISS (${F?.message??F})`)}else B(`model-custom: retain card state after checked MISS mutation=${P} streamingOff=${L} card=${D.slice(0,12)}`)}}return P&&L},H=async(_,D)=>{if(await z(_))return!0;let L=[...new Set(X)].join(`
251
+ `),F=`⚠️ 模型补录结果未能写回原卡。${D}${L?`
252
+ ${L}`:""}
253
+ 请重新发送 model 打开面板。`;if(!await I($.chatId,F))B(`model-custom: visible fallback send MISS (${D})`);return!1},G=(_)=>H(N3(!1,Y,_),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${_}。`);if(!V||!V.enabled)return await G("账号不可用"),!0;if(!Y)return await G("模型名为空"),!0;if(V.models.some((_)=>_.model.toLowerCase()===Y.toLowerCase()))return await H(N3(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;try{await hG(V.id,Y,$.codexAccountId())}catch(_){return B(`model-custom: config/refresh MISS (${x(_)})`),await G(`配置写入或模型刷新失败:${x(_)}`),!0}B(`model-custom: ${V.id} 补录 ${Y} by ${J}(记录已持久化)`);for(let _ of S$.all)for(let[D,P]of _.modelPanels)if(P.sourceId===V.id&&(_!==$||D!==Q.panelId))_.modelPanels.delete(D);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await G(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let K=MY($,W),j=K.find((_)=>_.model===Y);if(!j)return await G("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Q.panelId,{models:K,messageId:Q.cardMessageId}),j.unavailableReason||!j.efforts.length)return await H(N3(!0,Y,`**MISS**:${j.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Y} 已补录,能力尚未确认。`),!0;if(j.efforts.length===1){let _=await $.onModelEffortSelect(j.model,j.efforts[0].effort,Q.panelId,J,j.provider),D=(P)=>H(P.pending?A3(!0,P.message):P.ok?K6({sessionName:$.sessionName,provider:j.provider,model:j.model,effort:j.efforts[0].effort,scope:AY($,j.provider??"codex")}):A3(!1,P.message),P.message);if(await D(_),_.completion)_.completion.then(D).catch(async(P)=>{let L=`模型补录后的切换结果呈现失败:${x(P)}`;B(`model-custom: ${L}`),await I($.chatId,`❌ ${L}`)});return!0}return await H(W6({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:j}),`✅ 模型 ${Y} 已补录成功。`),!0}async function GB($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:G6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:G6($.sessionName)}}function _N($,Z){return g$(Z?.provider)?Z.provider:W4($)}function AY($,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`下次启动 ${i0(Z)} 时使用。`}async function WB($,Z,J="",Q="",Y=null){let V=Z.trim();if(!V)return await b($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=_N(V,Y),z=$.modelPanels.get(J.trim())?.models.find((H)=>H.model===V&&(H.provider??"codex")===X);if(!z)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(z.unavailableReason)return{ok:!1,message:z.unavailableReason};if(z.enabled===!1)return{ok:!1,message:`${z.displayName} 未配置,请先点「启用」`};if(z.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(z.efforts.length===1)return NY($,V,z.efforts[0].effort,J,Q,X);return{ok:!0,message:"",card:kQ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:z})}}async function NY($,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(),z=J.trim();if(!X)return{ok:!1,message:"模型为空"};let H=Q.trim(),G=$.modelPanels.get(H),W=g$(V)?V:G?.models.find((O)=>O.model===X)?.provider??W4(X);if(W==="dsh"){if(!O0(z))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(W==="claude"){if(!R0(z))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!_$(z))return{ok:!1,message:"Codex reasoning effort 无效"};let K=z,j=G?.models.find((O)=>O.model===X&&(O.provider??"codex")===W);if(!j||!j.efforts.some((O)=>O.effort===K))return{ok:!1,message:`${i0(W)} · ${X}/${K} 不在选项中`};let _=$.tokenSource(j.sourceId);if(_?.modelCatalogState){if(!_.enabled||_.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${_.modelCatalogState.error??_.modelCatalogState.status}`};if(!_.models.some((O)=>O.model===X&&O.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let D=!!j.sourceId&&$.currentTokenSource()?.id!==j.sourceId,P=!$.processSourceMatches(_,X)||!!_?.modelEnvironmentRevision&&_.modelEnvironmentRevision($.currentModelLabel()??"")!==_.modelEnvironmentRevision(X),L=$.modelSelectionNeedsProcessStop(W,j.sourceId??$.selectedTokenSourceId,X,K);if($.currentProvider()===W&&!D&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!L&&!P)return $.modelPanels.delete(H),{ok:!0,message:`当前已是 ${i0(W)} · ${X} / ${K}`,card:O3({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 后再切换到 ${i0(W)}`};let A=$.currentModelLabel()!==X||D,M=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((P||L)&&$.proc?.isAlive()&&M)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(W==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&A&&M)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===W&&!D&&!P&&!L){let T=j.sourceId?$.tokenSource(j.sourceId)?.resolveSpawnModel(X)??X:X;if(W==="codex")await $.proc.setModelSettings(T,K);else return await BN($,$.proc,X,T,K,H,j.sourceId)}await $.applyModelSelectionUnlocked(W,X,K,j.sourceId);let O=AY($,W);return $.modelPanels.delete(H),{ok:!0,message:`已选择 ${i0(W)} · ${X} / ${K}`,card:O3({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:O})}}catch(O){let T=`模型切换失败: ${x(O)}`;return B(`session "${$.sessionName}": set model settings failed: ${x(O)}`),{ok:!1,message:T}}}var FY=20;var KB=R(()=>{_0();RY();z0();IJ();J1();_0();M$();G1();$0();h()});import{createHash as PN}from"node:crypto";function qN($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function y3($="default"){return LB(_B($))}function jB($="default"){return DN(_B($))}function _B($){return d0().map((Z)=>Z.forAccount?.($)??Z)}async function DN($){let Z=LB($),Q=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((H)=>H.tokenSourceId===V.id);if(X)return X;let z=await FN(V);return z===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:z}}))).filter((V)=>V!==null),Y=new Set(Q.map((V)=>V.tokenSourceId));return PB(Z.identities.filter((V)=>!Y.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Y.has(V.tokenSourceId)),...Q])}function FN($){return UN($)}async function UN($){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 LB($){let Z=[],J=[];for(let Q of $)MN(Q,Z,J);return PB(Z,J)}function PB($,Z){return{catalogGeneration:PN("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function MN($,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(ON($,Y,Q))}function ON($,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:qN($.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:BB($.defaultModel)===BB(Z.model),status:Q,...Y?{reason:Y}:{},spawnRevision:$.spawnRevision}}function BB($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var R6=R(()=>{h();z0()});import{randomUUID as AN}from"node:crypto";async function qB($,Z){if(!Z.trim()){await I($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}UB();let J=`agents_${AN()}`;f3.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()});let Q;if(!await n($.chatId,FB(J),(V)=>{Q=V}))await I($.chatId,`❌ agents 面板发送失败
254
+ ${w(Q)}`)}function DB($,Z,J){let Q=TN($,J),Y=Number(Z);if(!Number.isInteger(Y))return EN("无效页码");let V=RN(Q.codexAccountId);return Q.page=Math.max(0,Math.min(V-1,Y)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:FB($)}}function FB($){let Z=f3.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=y3(Z.codexAccountId),Q=Math.max(1,Math.ceil(J.identities.length/T6));Z.page=Math.min(Z.page,Q-1);let Y=Z.page*T6;return iQ({panelId:$,page:Z.page,totalPages:Q,catalog:J.identities.slice(Y,Y+T6),failures:J.sourceFailures})}function RN($){return Math.max(1,Math.ceil(y3($).identities.length/T6))}function TN($,Z){UB();let J=f3.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function EN($){return{ok:!1,message:$,card:g1({title:"agents",message:$,ok:!1})}}function UB(){let $=Date.now()-NN;for(let[Z,J]of f3)if(J.createdAt<$)f3.delete(Z)}var T6=8,NN=1800000,f3;var MB=R(()=>{M$();$0();R6();f3=new Map});var xY={};r$(xY,{withTasklistLifecycleLock:()=>C6,tasklistNameForProject:()=>S6,reconcileTasklistDeletions:()=>bN,isTasklistAlreadyDeletedError:()=>OB,getTasklistBinding:()=>L1,enableTasklist:()=>TY,deleteTasklistRemoteIdempotently:()=>AB,deleteTasklist:()=>EY});import{existsSync as SN,readFileSync as CN}from"node:fs";function S6($){return`${$}[lodestar]`}function L1($){let Z=_1.get($);return Z?o4(Z):null}async function C6($,Z){let J=E6.get($)??Promise.resolve(),Q,Y=new Promise((X)=>{Q=X}),V=J.catch(()=>{}).then(()=>Y);E6.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Q(),E6.get($)===V)E6.delete($)}}function OB($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function AB($,Z=wZ){try{return await Z($),"deleted"}catch(J){if(OB(J))return"already_deleted";throw J}}async function TY($,Z){return await C6($,async()=>{let J=L1($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=S6($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await bZ(Z),V=await kZ(Q,Y),X={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Y,createdAt:V.createdAt};return x6($,X),o4(X)})}async function EY($,Z){return await C6($,async()=>{let J=L1($);if(!J)throw Error("tasklist is not enabled");if(J.guid!==Z)throw Error(`tasklist binding changed: current=${J.guid} requested=${Z}`);if(!J.deleting)J.deleting={requestedAt:new Date().toISOString(),attempts:0},x6($,J);return await NB($,Z)})}async function NB($,Z){let J=L1($);if(!J||J.guid!==Z)throw Error(`tasklist binding changed during deletion: ${$}`);J.deleting??={requestedAt:new Date().toISOString(),attempts:0},J.deleting.attempts++,J.deleting.lastAttemptAt=new Date().toISOString(),J.deleting.lastError=void 0,x6($,J);try{if(await AB(Z)==="already_deleted")B(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(_1);return Y.delete($),RB(Y),_1.delete($),o4(J)}catch(Q){let Y=L1($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),x6($,Y);throw Q}}async function bN(){let $=[..._1.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await C6(J.projectName,()=>NB(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 kN(){if(!SN(d3))return;try{let $=JSON.parse(CN(d3,"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:wN(Q.deleting)};_1.set(Z,Y)}B(`tasklist: loaded ${_1.size} project bindings`)}catch($){B(`tasklist: load map failed: ${$}`)}}function wN($){if(!$||typeof $!=="object")return;let Z=$;if(typeof Z.requestedAt!=="string"||!Z.requestedAt)return;return{requestedAt:Z.requestedAt,lastAttemptAt:typeof Z.lastAttemptAt==="string"?Z.lastAttemptAt:void 0,attempts:typeof Z.attempts==="number"&&Number.isFinite(Z.attempts)&&Z.attempts>=0?Math.floor(Z.attempts):0,lastError:typeof Z.lastError==="string"?Z.lastError:void 0}}function x6($,Z){let J=new Map(_1);J.set($,o4(Z)),RB(J),_1.set($,o4(Z))}function RB($=_1){let Z={};for(let[J,Q]of $)Z[J]=o4(Q);a(d3,Z)}function o4($){return JSON.parse(JSON.stringify($))}var _1,E6;var SY=R(()=>{H0();$0();h();x0();_1=new Map,E6=new Map;kN()});function c1($,Z,J=!1){let Q=$.worktreeProjectName();return uQ({projectName:Q,tasklistName:S6(Q),binding:L1(Q),notice:Z,confirmDelete:J})}async function TB($){let Z;if(!await n($.chatId,c1($),(Q)=>{Z=Q}))await I($.chatId,`❌ task 面板发送失败
255
+ ${w(Z)}`)}async function EB($){let Z=$.worktreeProjectName();try{let J=L1(Z),Q=await TY(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:c1($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${x(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${x(J)}`),{ok:!1,message:Q,card:c1($,{type:"error",content:`❌ ${Q}`})}}}function xB($,Z){let J=$.worktreeProjectName(),Q=L1(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:c1($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:c1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:c1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function SB($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let V=`已删除 ${(await EY(J,Q)).name}`;return{ok:!0,message:V,card:c1($,{type:"success",content:`✅ ${V}`})}}catch(Y){let V=`删除失败: ${x(Y)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${x(Y)}`),{ok:!1,message:V,card:c1($,{type:"error",content:`❌ ${V}`})}}}var CB=R(()=>{M$();$0();h();SY()});import{open as yN}from"node:fs/promises";import{basename as fN}from"node:path";function CY($){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 P1($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class bB{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:X0,getToken:m$,retry:t1,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(),z=Q?.(),H=z instanceof FormData,G=this.deps.intervalMs-(Date.now()-this.lastStartedAt);if(G>0)await this.deps.wait(G);Y?.throwIfAborted(),this.lastStartedAt=Date.now();let W=AbortSignal.timeout(gN),K=new AbortController,j=()=>K.abort(W.reason),_=()=>K.abort(Y.reason);W.addEventListener("abort",j,{once:!0}),Y?.addEventListener("abort",_,{once:!0});let D=K.signal;try{let P=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!H&&z!==void 0?{"Content-Type":"application/json"}:{}},...z!==void 0?{body:H?z:JSON.stringify(z)}:{},signal:D});return(await B$(P,$)).data}catch(P){if(D.aborted&&D.reason?.name==="TimeoutError")throw D.reason;throw P}finally{W.removeEventListener("abort",j),Y?.removeEventListener("abort",_)}}));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:P1(J?.token,"交付文件夹"),url:CY(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return P1(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Q=P1(J?.token,"群文件夹");if(Q!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Q,url:CY($.url),name:P1(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 y0&&Y.code===99991672)Y.message=`同步群文件夹名称需要应用身份权限 drive:file:upload;${Y.message}`;throw Y}let Q=await this.getFolder($,J);if(Q.name!==Z)throw Error("群文件夹名称更新未生效");return Q}async grantFolderAccess($,Z,J,Q){P1(Z,"交付群"),P1(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,z,H]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((W)=>W.member_type===X&&W.member_id===z)?.perm!==H)throw Error(`交付文件夹权限未生效:${X} / ${H}`)}async closeFileLinkSharing($,Z){P1($,"交付文件");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 yN($,"r");try{let V=await Y.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=fN($),z={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},H;if(V.size<=hN){let P=await Y.readFile(),L=await Y.stat();if(P.length!==V.size||L.mtimeMs!==V.mtimeMs||L.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");H=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let F=new FormData;for(let[U,A]of Object.entries(z))F.append(U,String(A));return F.append("file",new Blob([Uint8Array.from(P)]),X),F},Q)}else{let P=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>z,Q),L=P1(P?.upload_id,"分片上传事务"),F=P?.block_size,U=P?.block_num;if(!Number.isSafeInteger(F)||F<=0||F>IN||!Number.isSafeInteger(U)||U!==Math.ceil(V.size/F))throw Error("云空间返回的分片策略无效");for(let M=0;M<U;M++){Q?.throwIfAborted();let O=Math.min(F,V.size-M*F),T=Buffer.alloc(O),k=0;while(k<O){let E=await Y.read(T,k,O-k,M*F+k);if(!E.bytesRead)throw Error("交付文件在分片读取时发生变化");k+=E.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let E=new FormData;return E.append("upload_id",L),E.append("seq",String(M)),E.append("size",String(O)),E.append("file",new Blob([Uint8Array.from(T)]),X),E},Q)}let A=await Y.stat();if(A.size!==V.size||A.mtimeMs!==V.mtimeMs||A.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");H=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:L,block_num:U}),Q)}let G=P1(H?.file_token,"已上传文件"),W={token:G,url:"",name:X,bytes:V.size},K=[];try{J(W)}catch(P){K.push(P)}try{await this.closeFileLinkSharing(G)}catch(P){K.push(P)}if(K.length===1)throw K[0];if(K.length>1)throw AggregateError(K,K.map((P)=>P instanceof Error?P.message:String(P)).join(";"));Q?.throwIfAborted();let j=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:G,doc_type:"file"}],with_url:!0}),Q),_=j?.metas?.find((P)=>P.doc_token===G&&P.doc_type==="file");if(j?.failed_list?.length||!_)throw Error("已上传文件的元数据 MISS");let D={...W,url:CY(_.url)};return J(D),D}finally{await Y.close()}}}var hN=20971520,IN=20971520,gN=60000,I2;var kB=R(()=>{p0();$0();o2();I2=new bB});import{randomUUID as wB}from"node:crypto";import{basename as mN}from"node:path";class bY{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:wB(),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:wB(),path:$,name:mN($),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}
256
+ ${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{let Z;if($=await this.deps.sendCard(this.snapshot,(J)=>{Z=J}),!$)throw Error(`飞书未返回交付卡消息 ID:${w(Z)}`)}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?`
257
+ 已上传文件所在文件夹:${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 vB=()=>{};class kY{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=Q$(Z),Q=this.load(),Y=Q.workspaces[J]?.enabled;if(Y===void 0){let X=new Set(this.legacyChats($,J).map((z)=>Q.groups[z].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=Q$(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=Q$(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)||!h3(Z.groups)||Z.version===2&&!h3(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Y,V]of Object.entries(Z.workspaces??{})){if(!h3(V)||typeof V.enabled!=="boolean"||Q$(Y)!==Y)throw Error("工作目录文件交付开关无效");J.workspaces[Y]={enabled:V.enabled}}for(let[Y,V]of Object.entries(Z.groups)){if(!Y||!h3(V))throw Error("群文件夹绑定无效");let X=Z.version===1?V.enabled:V.legacyEnabled;if((Z.version===1||X!==void 0)&&typeof X!=="boolean")throw Error("群文件交付开关无效");if(X&&!V.folder)throw Error("已启用的旧群缺少文件夹绑定");if(V.folder!==void 0)pN(V.folder);J.groups[Y]={...V.folder?{folder:structuredClone(V.folder)}:{},...X===void 0?{}:{legacyEnabled:X}}}let Q=new Map;for(let[Y,V]of Object.entries(J.groups)){if(!V.folder)continue;let X=Q.get(V.folder.token);if(X!==void 0)throw Error(`云空间文件夹重复绑定到多个群:${X} / ${Y}`);Q.set(V.folder.token,Y)}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&&Q$(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){for(let[Q,Y]of Object.entries(this.load().groups))if(Q!==$&&Y.folder?.token===Z.token)throw Error("云空间文件夹已绑定其他群,不能共用交付目录");let J=structuredClone(this.load());J.groups[$]={...J.groups[$],folder:Z},this.commit(J)}commit($){this.deps.write($),this.state=$}}function h3($){return!!$&&typeof $==="object"&&!Array.isArray($)}function pN($){if(!h3($)||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 yB=R(()=>{U4()});import{join as cN}from"node:path";import{readFileSync as lN}from"node:fs";function fB($){return new bY($,{resolveFolder:(Z,J)=>s4.resolveFolder(Z,J),uploadFile:(Z,J,Q,Y)=>I2.uploadFile(Z,J,Q,Y),sendCard:(Z,J)=>n($.chatId,YQ(Z),J),persist:(Z)=>a(cN(UV,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await b($.chatId,Z))throw Error(Z)}})}var s4;var hB=R(()=>{$0();kB();vB();I7();H0();x0();h();yB();U4();s4=new kY({read:()=>{try{return lN(V5,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>a(V5,$),workDirForChat:($)=>{let Z=[...L0].filter(([,Y])=>Y===$).map(([Y])=>Y),J=P0.get($);if(!Z.length&&J)Z.push(J);let Q=new Set(Z.map((Y)=>Q$(O4(Y))));if(Q.size>1)throw Error(`旧文件交付群绑定了多个工作目录: ${$}`);return Q.values().next().value},getChatName:($,Z)=>I2.getChatName($,Z),createFolder:($,Z)=>I2.createFolder($,Z),getFolder:($,Z)=>I2.getFolder($,Z),renameFolder:($,Z,J)=>I2.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Q)=>I2.grantFolderAccess($,Z,J,Q)})});async function IB($,Z,J,Q,Y,V){let X,z="",H="";try{switch(Q.trim().toLowerCase()){case"":case"status":X=Y.get($);break;case"on":X=await Y.enable($,J),z="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Y.disable($),z="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(K){H=K instanceof Error?K.message:String(K);try{X=Y.get($)}catch{X=void 0}}let G=VQ({groupName:Z,workDir:V,settings:X,notice:z,error:H}),W;if(!await Y.sendCard(G,(K)=>{W=K}))await Y.reportError(`❌ 文件交付设置卡发送失败:${w(W)}${H?`
258
+ 设置失败:${H}`:""}`)}var gB=R(()=>{I7()});function mB($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
259
+ `)}function pB($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",mB(Z),"- 文件交付约定由 Lodestar 按工作目录设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写工作目录配置。"}`,J[$],...uN].join(`
260
+ `)}function cB($){return`[Lodestar 文件交付约定更新]
260
261
  以下约定从本轮起完整替换此前的文件交付约定:
261
- ${wB($)}`}var CN;var kY=N(()=>{CN=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});function I2($){return n8(X1($.sessionName)??$.sessionName)}function t4($){return O4(I2($))}function hB($){return O4($.sessionName)}function IB($,Z,J=$.currentProvider()){let Q=vB(J,Z),Y=h3($);return Y?`${Q}
262
- ${Y}`:Q}function gB($,Z){return h3($)??""}function wY($){return h3($)?"已载入wt特殊约定":null}function mB($,Z){let J=wY($);return J?`${Z}
263
- ${J}`:Z}function h3($){let Z=I2($),J=pz($.workDir,t4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
264
- `)}async function pB($,Z,J){if(!Z){await vY($);return}let Q=j2(Z);if(!Q){await k($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await k($.chatId,"❌ 找不到发起人,不能拉群。");return}let Y=I2($),V=t4($);try{await i8(V,async()=>{let X;try{X=lz(V,Y,Q)}catch(z){await k($.chatId,`❌ wt 失败: ${S(z)}`);return}try{let z=await $J(X.chatName,J),H=z.created?"已创建":z.joined?"已加入":"已在群内",G;if(!await i($.chatId,N3({slug:Q,branch:X.branch,status:H}),(_)=>{G=_}))await I($.chatId,`❌ wt 卡片失败: ${Q}
265
- ${v(G)}`);let K;if(!await i(z.chatId,N3({slug:Q,branch:X.branch,status:"就绪",body:"开始吧。"}),(_)=>{K=_}))await I(z.chatId,`❌ wt 卡片失败: ${Q}
266
- ${v(K)}`)}catch(z){await k($.chatId,`❌ wt 已建,拉群失败: ${S(z)}`)}})}catch(X){await k($.chatId,`❌ wt 失败: ${S(X)}`)}}async function cB($,Z){let J=I2($),Q=t4($);return await i8(Q,async()=>{return await bN(J,Q,Z)})}async function bN($,Z,J){let Q=cz(Z,$),Y=Q.filter((z)=>z.state==="merged"&&!z.mounted).length,V=Q.filter((z)=>z.state!=="merged"||z.mounted),X=await J7();return vQ({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Y,notice:J,entries:V.map((z)=>{let H=X.get(z.chatName)??[],G=P0.get(z.chatName),W=G&&H.includes(G)?G:H.length===1?H[0]:null;return{slug:z.slug,chatName:z.chatName,branch:z.branch,state:z.state,path:z.worktreePath??z.expectedPath,mounted:z.mounted,dirtyCount:z.dirtyCount,statusLine:z.statusLine,error:z.error,chatId:W,duplicateChatCount:H.length}})})}async function vY($){try{let Z=await cB($),J;if(!await i($.chatId,Z,(Y)=>{J=Y}))await I($.chatId,`❌ wt 列表失败
267
- ${v(J)}`)}catch(Z){await k($.chatId,`❌ wt 列表失败: ${S(Z)}`)}}async function fB($,Z,J,Q){try{return{ok:Z,message:J,card:await cB($,{type:Q,content:J})}}catch(Y){let V=`列表刷新失败: ${S(Y)}`;return B(`session "${$.sessionName}": wt action panel refresh failed: ${S(Y)}`),{ok:!1,message:`${J}
268
- ${V}`,card:N3({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function lB($,Z){let J=j2(Z);if(!J)return fB($,!1,"❌ 名称无效","error");let Q=I2($),Y=t4($),V;try{V=await i8(Y,async()=>{let X=D4(Q,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};FZ(Y,Q,J);let z=await JJ(X),H=uz(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,H.removedWorktree?"dir removed":"dir missing",z.disbanded?"group removed":"group missing",H.branch].join(`
269
- `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${S(X)}`,type:"error"}}return fB($,V.ok,V.message,V.type)}var uB=N(()=>{kY();M$();$0();h();NZ()});import{closeSync as wN,openSync as vN,readSync as yN,readdirSync as fN,statSync as hN}from"node:fs";import{randomUUID as fY}from"node:crypto";import{join as IN}from"node:path";function b6($){return X1($.sessionName)??$.sessionName}function iB($){let Z=aZ($,yY);return yY.add(Z),Z}function nB($){yY.delete($)}function r4($){let Z=dB.get($);if(!Z)Z=new Map,dB.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let V=Y.status==="consumed"?pN:mN,X=Y.consumedAt??Y.createdAt;if(J-X>V)Z.delete(Q)}return Z}function lN($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function aB($,Z,J,Q){let Y={id:fY(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:b6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return r4($).set(Y.id,Y),Y}function hY($,Z,J,Q,Y){let V=r4($).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||!lN(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 C6($){$.status="consumed",$.consumedAt=Date.now()}function uN($){return{kind:"fork",source:$.source,through:$}}function dN($){return N4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function iN($){let Z=R4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return M0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function nN($){let Z=h8($),J;try{J=fN(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(V4("claude",V))continue;let X=IN(Z,Y),z;try{z=hN(X).mtimeMs}catch(H){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${H?.message??H}`)}Q.push({provider:"claude",sessionId:V,cwd:$,preview:oN(X),ts:z})}return Q.sort((Y,V)=>V.ts-Y.ts)}function aN($){let Z=$.slice().sort((Y,V)=>V.ts-Y.ts),J=Date.now()-gN,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(cN,Math.max(10,Q)))}function oN($){let Z="",J=null;try{J=vN($,"r");let Y=Buffer.alloc(65536),V=yN(J,Y,0,65536,0);Z=Y.subarray(0,V).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)wN(J)}let Q="";for(let Y of Z.split(`
270
- `)){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 z=X.content.trim();if(z)return z.slice(0,80)}if(!Q&&X.type==="user"&&X.message){let z=sN(X.message);if(z)Q=z}}return Q.slice(0,80)}function sN($){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 oB($,Z,J){if(!J){await k($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=dN($),Y=iN($),V=new Map,X=[];for(let K=0;K<Q.length;K++){let j=Q[K];if(K===0&&Y===null)continue;let _=fY(),D=K===0?Y:uN(Q[K-1].checkpoint);V.set(_,{kind:Z,launch:D,branchBase:Y,seedAnchors:Q.slice(0,K),writes:Q.slice(K).flatMap((L)=>L.writes)}),X.push({choiceId:_,preview:j.preview,ts:j.ts})}X.reverse();let z=aB($,Z,J,V),H=fQ({projectName:b6($),panelId:z.id,mode:Z,entries:X}),G,W;try{G=await i($.chatId,H,(K)=>{W=K})}catch(K){throw r4($).delete(z.id),K}if(!G)r4($).delete(z.id),await I($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败
271
- ${v(W)}`)}function sB($,Z){return oB($,"fork",Z)}function tB($,Z){return oB($,"back",Z)}async function rB($,Z){if(!Z){await k($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():nN($.workDir)}catch(G){await I($.chatId,`❌ 历史会话读取失败: ${G instanceof Error?G.message:G}`);return}let Q=new Map,Y=aN(J).map((G)=>{let W=fY();return Q.set(W,{kind:"resume",launch:{kind:"fork",source:{provider:G.provider,sessionId:G.sessionId,cwd:G.cwd}},sourcePreview:G.preview,sourceTs:G.ts,sourceStatus:G.status}),{choiceId:W,preview:G.preview,ts:G.ts}}),V=aB($,"resume",Z,Q),X=hQ({projectName:b6($),panelId:V.id,entries:Y}),z,H;try{z=await i($.chatId,X,(G)=>{H=G})}catch(G){throw r4($).delete(V.id),G}if(!z)r4($).delete(V.id),await I($.chatId,`❌ rs 历史列表发送失败
272
- ${v(H)}`)}async function eB($,Z){if(!Z){await k($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await k($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=iB(b6($));await k($.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{nB(J)}if(!Q.ok){await k($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await k($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function $j($){if(!X1($.sessionName)){await k($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await k($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await k($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await k($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function Zj($,Z,J,Q){let Y=hY($,"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 z=iB(V.baseName);B(`session-temp: fork ${$.sessionName} → ${z} (${X.launch.kind})`),await k($.chatId,`\uD83D\uDD31 正在分叉到 ${z}…`);let H;try{H=await $.opts.onCreateTempSession({chatName:z,userOpenId:Q,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{nB(z)}if(!H.ok)return{ok:!1,message:`分叉失败: ${H.error??"未知"}`};return{ok:!0,message:`已分叉到 ${z};原会话和磁盘文件未回滚`}}catch(z){return{ok:!1,message:`分叉失败: ${z instanceof Error?z.message:z}`}}finally{C6(V)}}async function Jj($,Z,J,Q){let Y=hY($,"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 z="";try{let W;if(!await i($.chatId,IQ({projectName:V.baseName,entries:X.writes}),(j)=>{W=j}))z=`;文件变更记录卡发送失败: ${v(W)}`}catch(W){z=`;文件变更记录卡发送失败: ${v(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:`回退失败;原会话绑定未改,请检查日志后重试${z}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${z}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${S0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${z}`}}catch(z){return{ok:!1,message:`回退失败: ${z instanceof Error?z.message:z}`}}finally{C6(V)}}async function Qj($,Z,J,Q){let Y=hY($,"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 C6(V),Error("resume panel contained a non-resume choice");let z=X.launch.source.sessionId,H=$.lastSessionId,G=(K,j)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:z,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:H,newSessionId:K,bindingState:j}),W=(K,j,_,D=null)=>({ok:K,message:j,resumePresentation:G(D,_)});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} ${z}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:H}:null}))return W(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return W(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let j=$.lastSessionId;if(!j)return W(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(j===z||H&&j===H)return W(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",j);return W(!0,"已创建并接入独立分支;源会话未修改","changed",j)}catch(K){return W(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{C6(V)}}var gN=86400000,mN=1800000,pN=3600000,cN=40,dB,yY;var Yj=N(()=>{$0();M$();h();_4();q9();r1();dB=new WeakMap,yY=new Set});import{existsSync as Vj}from"node:fs";import{randomBytes as IY,timingSafeEqual as rN}from"node:crypto";import{isAbsolute as eN}from"node:path";function mY($,Z=new Set){if($ instanceof X4)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=mY(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return mY($.cause,Z);return null}function $R($){return $.itemId||$.turnId||"__latest__"}function Xj($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function ZR($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function JR($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function v6(){return m.runtime?.live_elapsed??"bucket"}function Gj($,Z){return`${$} (${p4(Date.now()-Z,v6()).label})`}function e4($){return $.length?$.map((Z)=>`${Z.operation}: ${v(Z)}`).join(`
273
- `):v(void 0)}function zR($,Z){let J=Z?.apiMessage??Z?.message??"MISS";for(let Q of[Z?.cardId,Z?.elementId,Z?.targetElementId])if(Q)J=J.split(Q).join("<id>");return J=J.replace(/^cardkit\s+\S+\s+\S+\s+HTTP\s+\d+:\s*/i,"").replace(/\s+log_id=\S+/gi,"").replace(/\s+/g," ").trim(),`${$??"MISS"}:${Z?.httpStatus??"MISS"}:${J}`}var zj="Thinking...",QR="Writing...",YR="Working...",gY=1e4,k6=720000,VR=50,XR=256,w6=1e4,Hj=250,S$;var NY=N(()=>{q9();o9();_0();J1();sJ();_0();f0();ZQ();$Y();X0();j0();g4();_4();G1();M$();$0();h();H0();TQ();J$();I4();zK();FJ();JY();_K();EK();uK();M6();nK();gJ();oK();YB();_B();AB();CB();kB();kY();uB();Yj();r1();S$=class S${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=IY(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??XK(),S$.all.add(this);let Q=sZ($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=C0(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=b1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=T4($);if(V)if(this.selectedProvider!=="claude")V$($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{M0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,z=this.lastSessionRef,H=!X&&z?.provider==="claude"&&z.cwd===this.workDir&&z.sessionId!==V.launch.source.sessionId&&z.sessionId!==V.previousSessionId;if(!X&&!H)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`session "${$}": restored ${H?"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(j$(this.proc)).name}:{}}}get workDir(){return hB(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 e5(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?j$(this.proc):this.codexStartAccountOverride??y.selected(this.sessionName)}tokenSource($){let Z=C0($);return Z?.forAccount?G0($,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()===c?{}:{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=C0($.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)V$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;if(this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=b1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,w1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId),!Z?.codexApiProvider){let J=$.codexAccountId??c;if($.codexAccountAutomatic)y.selectAuto(this.sessionName);else if(y.selected(this.sessionName)!==J)y.select(this.sessionName,J)}}dshEffortForSpawn(){if(O0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&I$($,this.selectedModel??$.defaultModel);if(!Z||!O0(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 w4({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!V4("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");let $=this.currentTokenSource();if(!$?.codexApiProvider&&!u9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(z)=>Z.spawnEnv(z):void 0,Q=new z4({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(z){V=z}let X=null;try{await Q.kill(2000)}catch(z){X=z}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${S(V)}; ${S(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=I8(this.workDir,$.sessionId);if(!Vj(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${S0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{let J=this.currentTokenSource();if(!J?.codexApiProvider&&!u9(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 z4({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(z)=>Q.spawnEnv(z):void 0,...Q?.codexApiProvider?{apiProvider:Q.codexApiProvider}:{}}),V=null;try{Z=await Y.readConversationRef($.sessionId)}catch(z){V=z,Z=$}let X=null;try{await Y.kill(2000)}catch(z){X=z}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${S(V)}; cleanup=${S(X)}`);if(V)throw V;if(X)throw X}return M0({kind:"resume",source:Z},this.selectedProvider,this.workDir),m9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...S$.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 _$(this.selectedEffort)?this.selectedEffort:U9}return U9}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&R0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=I$($,this.selectedModel??$.defaultModel);if(!R0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return T1}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??I$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?T1:U9)}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"?T1:U9);return{provider:Z,model:Q,effort:Y}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}async replaceFooterContent($,Z){let J;return{landed:await B0($,b.footer,this.footerElement(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}),failure:J}}footerElement($){return{tag:"markdown",element_id:b.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return XQ($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return i0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(M0($.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=IY(32).toString("base64url");let Z={LODESTAR_AGENT_URL:c4(m.notify.bind,m.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"});M0(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(),z=H3({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:I9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:d2},hostEnv:Z});return this.procSourceRevisions.set(z.process,z.sourceRevision),this.procFileDeliveryModes.set(z.process,X),z.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=C0(V),z=X?Z||null:$==="codex"?null:Z,H=X?J??I$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,z,H);let G=Y!==$?{anchors:N4(this.sessionName).slice(),base:R4(this.sessionName),pending:T4(this.sessionName)}:null;if(G)V$(this.sessionName,[],null,null);try{w1(this.sessionName,$,z,H,V)}catch(W){if(G)try{V$(this.sessionName,G.anchors,G.base,G.pending)}catch(K){throw AggregateError([W,K],`model selection write failed: ${S(W)}; conversation state restore failed: ${S(K)}`)}throw W}if(G)this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=V,this.selectedModel=z,this.selectedEffort=H,this.lastSessionRef=b1(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()===G4($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===G4($,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(G){X=G}V=await this.settleProcResumableState(Y);let z=this.finishProcStop(Y,X);this.opts.onLifecycleChange?.();let H=[...X?[X]:!z?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...V?[Error(V)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(S).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(S).join("; ")}`);return!0}startFooterTimer($,Z,J=(Q)=>Q){let Q=Date.now(),Y=Z,V=!1,X=!1,z=!1,H=!1,G=null,W=()=>{if(V)return;if(X){H=!0;return}X=!0,H=!1;let j=Y;this.replaceFooterContent($,J(Gj(Y,Q))).then((_)=>{if(X=!1,V)return;if(_.landed){if(H)W();return}if(z=!0,G)clearTimeout(G);if(G=null,H&&Y!==j)W()})},K=()=>{if(V||z)return;let{nextDelayMs:j}=p4(Date.now()-Q,v6());G=setTimeout(()=>{W(),K()},Math.max(1,Math.ceil(j)))};return W(),K(),{setStatus(j){if(j===Y)return;Y=j,W()},stop(){if(V=!0,G)clearTimeout(G)},elapsedSec(){return(Date.now()-Q)/1000}}}async openStatusCard($,Z,J="blue"){let Q=Date.now(),Y=EQ({sessionName:this.sessionName,title:$,status:Gj(Z,Q),template:J}),V,X=await i(this.chatId,Y,(H)=>{V=H});if(!X)return B(`session "${this.sessionName}": status card send failed title=${$}`),await I(this.chatId,`❌ 创建状态卡片失败: ${$}
274
- ${v(V)}`),null;let z;try{z=await l$(X)}catch(H){return B(`session "${this.sessionName}": status card id_convert failed title=${$}: ${H}`),await I(this.chatId,`❌ 状态卡片初始化失败: ${$}
275
- ${v(H)}`),null}return E$(z,1),{cardId:z,title:$,timer:this.startFooterTimer(z,Z,(H)=>F3($,H))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=F3($.title,`${Z} (${E0(J)})`);await v1($.cardId);let Y=[],V=(H)=>{Y.push(H)},X=await B0($.cardId,b.footer,this.footerElement(Q),{onFailure:V});a0($.cardId);let z=await k0($.cardId,C2({durationSec:J,suffix:Z}),V);if(X&&z)await q$($.cardId);else{let H=`footer=${X?"ok":"MISS"}, settings=${z?"ok":"MISS"}`;B(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await I(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}
276
- ${e4(Y)}`)}}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&&rN(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?S(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 会话落盘确认失败: ${S(V)}`}let Q=$.conversationMaterializationFailure?.();if(Q&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${S(Q)}`;let Y=this.persistResumableSessionId(!1,$,!1);return[Z,Y].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,V$(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=G0("codex-sub",$)?.defaultModel||null;V$(this.sessionName,[],null,null),w1(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=b1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")w1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&j$(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 k(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&&!u9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){let W;if(!await i(this.chatId,n$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"}),(j)=>{W=j}))throw Error(`Codex 登录引导卡片发送失败:${v(W)}`)}return!1}if(!Vj(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await k(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{zJ(this.workDir)}catch(W){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${W}`),Z)await k(this.chatId,`❌ 创建项目失败: ${W}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Y;try{Y=this.spawnAgent()}catch(W){let K=`${this.backendLabel()} 启动失败: ${S(W)}`;if(B(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await k(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,Hj):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let z,H=null;try{Y.sendInitialize(),z=Y.initializationPromise?.()}catch(W){z=void 0,H=W}let G=H?{state:"error",error:H}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(z),()=>{B(`session "${this.sessionName}": codex init still pending after ${gY/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(G.state==="error"||G.state==="exit"){let W=G.error?S(G.error):G.state;B(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${W}`);let j=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动失败: ${W}${j}`;if(J?.(_),Z)await k(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="timeout"){B(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${k6/1000}s)`);let K=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${V} 启动超时: ${k6/1000} 秒内初始化事务未完成${K}`;if(J?.(j),Z)await k(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Y||!Y.isAlive()){let W=`${V} 启动期间已退出`;if(B(`session "${this.sessionName}": ${W}`),J?.(`❌ ${W}`),Z)await k(this.chatId,`❌ ${W}`);return this.detachProc(Y),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 i(this.chatId,n$({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let W=this.modelLine();await k(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),W].filter(Boolean).join(`
277
- `))}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=(z,H)=>{if(Q)return;Q=!0,clearTimeout(V),clearTimeout(X),J({state:z,error:H})},V=setTimeout(()=>{if(Q)return;try{Z?.()}catch(z){Y("error",z)}},gY),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${k6/1000}s`))},k6);$.then(()=>Y("init"),(z)=>Y("error",z)),this.proc?.quotaWaitPromise?.().then(()=>Y("waiting_quota"),(z)=>Y("error",z))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(G,W)=>{if(Q)return;Q=!0,clearTimeout(V),$.off("init",X),$.off("error",z),$.off("exit",H),J({state:G,error:W})},V=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),z=(G)=>Y("error",G),H=(G)=>Y("exit",G);$.once("init",X),$.once("error",z),$.once("exit",H)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)g0($,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)g0(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;this.daemonRestoreRequired=!1;let Y=this.proc;if(Y)this.beginProcStop(Y);let V=null;try{await this.cancelAgentRuns($)}catch(F){V=F}if(!Y){if(this.status="stopped",this.opts.onLifecycleChange?.(),V)throw V;if(Q?.("⚪ session 当前未运行"),J)await k(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let X=this.persistResumableSessionId(!1,Y,!1),z=null;if(Q?.(`\uD83D\uDED1 停止 ${this.backendLabel(Y.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: ${S(F)}`)});let H=this.waitForTurnCloses().catch((F)=>B(`session "${this.sessionName}": stop main-card close failed: ${S(F)}`));this.beginProcStop(Y),this.status="stopped";let G=[];try{this.opts.onLifecycleChange?.()}catch(F){G.push(F),B(`session "${this.sessionName}": stop intent lifecycle write failed: ${S(F)}`)}let W=Y.conversationMaterializationBarrier?.();if(W){try{await W}catch(F){z=`Codex 会话落盘确认失败: ${S(F)}`}X=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 K=null;try{await Y.kill()}catch(F){K=F}let j=Y.conversationMaterializationFailure?.();if(j&&Y.isConversationResumable?.()!==!0)z=`Codex 会话落盘确认失败: ${S(j)}`;X=this.persistResumableSessionId(!1,Y,!1);let D=(await Promise.allSettled([this.resetBackgroundTasks(),H])).filter((F)=>F.status==="rejected").map((F)=>F.reason);for(let F of D)B(`session "${this.sessionName}": stop terminal cleanup failed: ${S(F)}`);let L=this.finishProcStop(Y,K);try{this.opts.onLifecycleChange?.()}catch(F){G.push(F),B(`session "${this.sessionName}": stop final lifecycle write failed: ${S(F)}`)}let P=[...V?[V]:[],...K?[K]:[],...!L&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...D,...G,...X?[Error(X)]:[],...z&&Y.isConversationResumable?.()!==!0?[Error(z)]:[]];if(P.length===1)throw P[0];if(P.length>1)throw AggregateError(P,`stop failed: ${P.map(S).join("; ")}`);if(Q?.(`✅ ${$}`),J)await k(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 k(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,k1(this.sessionName,null),this.pendingConversationMaterialization=null;let z=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),H=this.lastSessionRef;if($&&!z&&H?.cwd===null)try{H=await this.resolveLegacyResumeRef(H),this.lastSessionRef=H,this.lastSessionId=H.sessionId}catch(C){let g=this.invalidateMissingCodexResume(H.sessionId,C,J),Y0=g?`❌ 旧会话不可恢复: ${S(C)};${g}`:`❌ 旧会话 cwd 校验失败: ${S(C)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Y?.(Y0),Q)await k(this.chatId,Y0);return!1}let G=H?.sessionId??null,W=z&&z.kind!=="fresh"?z.source.sessionId:G,K=W?S0(W):"",j=null,_=(C=this.proc)=>{if(!$||z||C?.provider!=="codex"||C.isConversationResumable?.()!==!0)return;j=this.persistResumableSessionId(!1,C,!1),H=this.lastSessionRef,G=H?.sessionId??null,W=G,K=W?S0(W):""},D=null;if(!Y&&Q&&$&&G){let C=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(D=await this.openStatusCard("restart",C),D)Y=(g)=>this.setStatusCard(D,g)}let L=Q&&!D,P=async(C)=>{if(D)await this.closeStatusCard(D,C)},F=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||cJ(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: ${S(C)}`)});let U=this.waitForTurnCloses().catch((C)=>B(`session "${this.sessionName}": restart main-card close failed: ${S(C)}`)),A=null,M=null,O=null;if(this.proc){let C=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(C.provider)}`),O=C;let g=this.agentCapability;this.beginProcStop(C);try{await this.cancelAgentRuns("会话正在重启")}catch(E){M=E}let Y0=C.conversationMaterializationBarrier?.();if(Y0)try{await Y0}catch(E){j=`Codex 会话落盘确认失败: ${S(E)}`}if(_(C),$&&!z&&j&&!M&&!F&&C.isAlive()){if(this.proc===C&&this.stoppingProc===C)this.stoppingProc=null,this.agentCapability=g;this.status=V;let E=`❌ ${this.backendLabel(C.provider)} 恢复点尚未安全落盘,已保留当前进程: ${j}`;if(B(`session "${this.sessionName}": abort restart before kill: ${j}`),Y?.(E),L)await k(this.chatId,E);return await P(E),!1}try{await C.kill()}catch(E){A=E}let e=C.conversationMaterializationFailure?.();if(e&&C.isConversationResumable?.()!==!0)j=`Codex 会话落盘确认失败: ${S(e)}`;_(C)}else try{await this.cancelAgentRuns("会话正在重启")}catch(C){M=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 w=(await Promise.allSettled([this.resetBackgroundTasks(),U])).filter((C)=>C.status==="rejected").map((C)=>C.reason);for(let C of w)B(`session "${this.sessionName}": restart terminal cleanup failed: ${S(C)}`);let T=O?this.finishProcStop(O,A):!0,f=[...M?[`agents=${S(M)}`]:[],...A?[`kill=${S(A)}`]:[],...!T&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...w.map((C)=>`cleanup=${S(C)}`),...j?[`resume=${j}`]:[]];if(f.length>0&&X)try{k1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(C){f.push(`pendingRestore=${S(C)}`)}if(f.length>0){let C=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${f.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(C),L)await k(this.chatId,C);return await P(C),!1}let u=z?.kind==="resume"||z?.kind==="fork";if($&&H||u){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let C;try{C=this.spawnAgent(H??void 0)}catch(n){let z0=`❌ ${this.backendLabel()} 恢复失败: ${S(n)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${S(n)}`),Y?.(z0),L)await k(this.chatId,z0);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(z0),!1}this.attachProc(C);let g=this.backendLabel(),Y0=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(C,Hj):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${g} 恢复启动`:`⏳ 等待 ${g} init 确认`);let e,E=null;try{C.sendInitialize(),e=C.initializationPromise?.()}catch(n){e=void 0,E=n}let x=E?{state:"error",error:E}:this.selectedProvider==="claude"?await Y0:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(e),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${gY/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${g} init 确认 thread=${K}`))});if(x.state==="error"||x.state==="exit"||x.state==="timeout"){let n=x.state==="error"?this.invalidateMissingCodexResume(W,x.error,J):null,z0=[x.error?S(x.error):x.state,n].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${z0}`);let p2=await this.stopOwnedProc(C,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,c2=x.state==="timeout"?`❌ ${g} 恢复超时${p2}`:`❌ ${g} 恢复失败: ${z0}${p2}`;if(Y?.(c2),L)await k(this.chatId,c2);return this.status="stopped",this.opts.onLifecycleChange?.(),await P(c2),!1}if(this.proc!==C||!C.isAlive()){let n=`❌ ${g} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(n),L)await k(this.chatId,n);return this.detachProc(C),this.status="stopped",this.opts.onLifecycleChange?.(),await P(n),!1}let p=this.withModel(this.withWorktreeInstructionNotice(x.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&x.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Y?.(p),L)await k(this.chatId,p);if(this.status=x.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),x.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await P(p)}catch(n){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${S(n)}`),await I(this.chatId,`⚠️ ${p}
278
- 状态卡收尾失败: ${S(n)}`)}return!0}else{if($&&!z){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),L)await k(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{M0($,this.selectedProvider,this.workDir);let J=T4(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)k1(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)k1(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{k1(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Y,V],`fork start and pending-intent restore failed: ${S(Y)}; ${S(V)}`)}throw Y}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{M0($,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,z=N4(this.sessionName).slice(),H=R4(this.sessionName),G=T4(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,j=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,A4(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)m9(this.sessionName,X);else A4(this.sessionName,this.selectedProvider);V$(this.sessionName,z,H,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},_=!1;if(Q?.pendingLaunch)V$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,_=!0;this.pendingConversationLaunch=$;let D=(L)=>{K=X?.provider==="codex"&&X.sessionId===L};try{let L;try{L=$.kind==="fresh"?await this.restartUnlocked(!1,J,D):await this.restartUnlocked(!0,J,D)}catch(P){let F=null,U=this.proc&&this.proc!==Y?this.proc:null;if(U)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(R){F=R}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!F)F=Error("replacement process stop was not confirmed");let M=null;if(A)try{j()}catch(R){M=R}let O=[P,...F?[F]:[],...M?[M]:[]];if(O.length===1)throw P;throw AggregateError(O,`rollback launch and cleanup failed: ${O.map(S).join("; ")}`)}if(!L)return j(),!1;if(Q)try{if(!_)V$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(P){let F=null,U=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(R){F=R}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!F)F=Error("replacement process stop was not confirmed");let M=null;if(A)try{j()}catch(R){M=R}let O=[P,...F?[F]:[],...M?[M]:[]];if(O.length===1)throw P;throw AggregateError(O,`rollback branch commit failed: ${O.map(S).join("; ")}`)}return L}finally{this.pendingConversationLaunch=null}})}dispose(){S$.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 nZ(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${S(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(...pQ(J.name,J.input));return Z}worktreeProjectName(){return I2(this)}worktreeProjectDir(){return t4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return IB(this,$)}delegatedAgentDeveloperInstructions($){return gB(this,$)}worktreeInstructionLoadedNotice(){return wY(this)}withWorktreeInstructionNotice($){return mB(this,$)}worktreeExtraInstruction(){return h3(this)}runWorktreeCommand($,Z){return pB(this,$,Z)}showWorktrees(){return vY(this)}showTasklistPanel(){return FB(this)}showAgentIdentityPanel($=""){return WB(this,$)}onAgentIdentityPage($,Z,J){return KB($,Z,J)}onTasklistEnable(){return UB(this)}onTasklistDeletePrompt($){return MB(this,$)}onTasklistDeleteConfirm($){return OB(this,$)}runCompactCommand(){return aK(this)}showModelPanel(){return tK(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>FY(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=`模型设置已完成,但排队输入提交失败:${S($)}`;B(`session "${this.sessionName}": ${Z}`),await I(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Q=null){return this.runLifecycle("model-select",()=>QB(this,$,Z,J,Q))}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>AY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return MY(this,$,Z)}onModelPage($,Z,J){return A6(this,$,Z,J)}onModelAddOpen($,Z){return rK(this,$,Z)}onModelListEdit($,Z,J,Q){return this.runLifecycle("model-list-edit",()=>eK(this,$,Z,J,Q))}onModelPanelCancel($=""){return JB(this,$)}onModelCustomPrompt($,Z,J=""){return $B(this,$,Z,J)}consumeModelCustomMessage($,Z){return ZB(this,$,Z)}onWorktreeDisband($){return lB(this,$)}showForkList($=""){return sB(this,$)}showBackList($=""){return tB(this,$)}showResumeList($=""){return rB(this,$)}runBtwCommand($){return eB(this,$)}runByeCommand(){return $j(this)}onForkSelect($,Z,J=""){return Zj(this,$,Z,J)}onBackSelect($,Z,J=""){return Jj(this,$,Z,J)}onResumeSelect($,Z,J=""){return Qj(this,$,Z,J)}runCommand($,Z="",J){return vG(this,$,Z,J)}getFileDeliveryMode(){return s4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return bB(this.chatId,this.sessionName,Z,$,{get:(J)=>s4.get(J,this.workDir),enable:(J,Q)=>s4.enable(J,this.workDir,Q),disable:(J)=>s4.disable(J,this.workDir),sendCard:(J,Q)=>i(this.chatId,J,Q),reportError:async(J)=>{if(B(`session "${this.sessionName}": ${J}`),!await k(this.chatId,J))throw Error(J)}},this.workDir)}async buildConsoleOpts($,Z){let J=await vW(),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:[...S$.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,accountUsages:await ZY(),sysinfo:J}}async buildConsoleCard($){return X6(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await ZY()}catch(Y){let V=S(Y);B(`console usage MISS: ${V}`),Z.accountUsages=[{id:"error",label:"额度",usage:{state:"network",windows:[],reason:V}}]}let J;if(!await B0($,b.consoleUsage,U3(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}))throw Error(`console usage element replace rejected: ${v(J)}`)}async mutateStaticCard($,Z,J){let Q=!0,Y=[];try{await J()}catch(X){Q=!1,Y.push(S(X)),B(`session "${this.sessionName}": ${Z} mutation failed: ${S(X)}`)}let V=!1;try{V=await k0($,{config:{streaming_mode:!1}},(X)=>{Y.push(v(X))})}catch(X){Y.push(v(X)),B(`session "${this.sessionName}": ${Z} streaming-off failed: ${S(X)}`)}if(!Q||!V)return B(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Q} streamingOff=${V} card=${$.slice(0,12)}`),await I(this.chatId,`⚠️ 卡片更新失败 (${Z})。
262
+ ${mB($)}`}var uN;var wY=R(()=>{uN=["- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会自动展示图片和提示词,支持时放进折叠面板,无法嵌入时单独发送。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"]});function g2($){return a8(X1($.sessionName)??$.sessionName)}function t4($){return O4(g2($))}function uB($){return O4($.sessionName)}function dB($,Z,J=$.currentProvider()){let Q=pB(J,Z),Y=I3($);return Y?`${Q}
263
+ ${Y}`:Q}function iB($,Z){return I3($)??""}function vY($){return I3($)?"已载入wt特殊约定":null}function nB($,Z){let J=vY($);return J?`${Z}
264
+ ${J}`:Z}function I3($){let Z=g2($),J=az($.workDir,t4($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
265
+ `)}async function aB($,Z,J){if(!Z){await yY($);return}let Q=_2(Z);if(!Q){await b($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await b($.chatId,"❌ 找不到发起人,不能拉群。");return}let Y=g2($),V=t4($);try{await n8(V,async()=>{let X;try{X=sz(V,Y,Q)}catch(z){await b($.chatId,`❌ wt 失败: ${x(z)}`);return}try{let z=await ZJ(X.chatName,J),H=z.created?"已创建":z.joined?"已加入":"已在群内",G;if(!await n($.chatId,R3({slug:Q,branch:X.branch,status:H}),(_)=>{G=_}))await I($.chatId,`❌ wt 卡片失败: ${Q}
266
+ ${w(G)}`);let K;if(!await n(z.chatId,R3({slug:Q,branch:X.branch,status:"就绪",body:"开始吧。"}),(_)=>{K=_}))await I(z.chatId,`❌ wt 卡片失败: ${Q}
267
+ ${w(K)}`)}catch(z){await b($.chatId,`❌ wt 已建,拉群失败: ${x(z)}`)}})}catch(X){await b($.chatId,`❌ wt 失败: ${x(X)}`)}}async function oB($,Z){let J=g2($),Q=t4($);return await n8(Q,async()=>{return await dN(J,Q,Z)})}async function dN($,Z,J){let Q=oz(Z,$),Y=Q.filter((z)=>z.state==="merged"&&!z.mounted).length,V=Q.filter((z)=>z.state!=="merged"||z.mounted),X=await Q7();return yQ({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Y,notice:J,entries:V.map((z)=>{let H=X.get(z.chatName)??[],G=L0.get(z.chatName),W=G&&H.includes(G)?G:H.length===1?H[0]:null;return{slug:z.slug,chatName:z.chatName,branch:z.branch,state:z.state,path:z.worktreePath??z.expectedPath,mounted:z.mounted,dirtyCount:z.dirtyCount,statusLine:z.statusLine,error:z.error,chatId:W,duplicateChatCount:H.length}})})}async function yY($){try{let Z=await oB($),J;if(!await n($.chatId,Z,(Y)=>{J=Y}))await I($.chatId,`❌ wt 列表失败
268
+ ${w(J)}`)}catch(Z){await b($.chatId,`❌ wt 列表失败: ${x(Z)}`)}}async function lB($,Z,J,Q){try{return{ok:Z,message:J,card:await oB($,{type:Q,content:J})}}catch(Y){let V=`列表刷新失败: ${x(Y)}`;return B(`session "${$.sessionName}": wt action panel refresh failed: ${x(Y)}`),{ok:!1,message:`${J}
269
+ ${V}`,card:R3({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function sB($,Z){let J=_2(Z);if(!J)return lB($,!1,"❌ 名称无效","error");let Q=g2($),Y=t4($),V;try{V=await n8(Y,async()=>{let X=D4(Q,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};UZ(Y,Q,J);let z=await QJ(X),H=tz(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,H.removedWorktree?"dir removed":"dir missing",z.disbanded?"group removed":"group missing",H.branch].join(`
270
+ `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${x(X)}`,type:"error"}}return lB($,V.ok,V.message,V.type)}var tB=R(()=>{wY();M$();$0();h();RZ()});import{closeSync as nN,openSync as aN,readSync as oN,readdirSync as sN,statSync as tN}from"node:fs";import{randomUUID as hY}from"node:crypto";import{join as rN}from"node:path";function k6($){return X1($.sessionName)??$.sessionName}function eB($){let Z=oZ($,fY);return fY.add(Z),Z}function $j($){fY.delete($)}function r4($){let Z=rB.get($);if(!Z)Z=new Map,rB.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let V=Y.status==="consumed"?ZR:$R,X=Y.consumedAt??Y.createdAt;if(J-X>V)Z.delete(Q)}return Z}function QR($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function Zj($,Z,J,Q){let Y={id:hY(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:k6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return r4($).set(Y.id,Y),Y}function IY($,Z,J,Q,Y){let V=r4($).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||!QR(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 b6($){$.status="consumed",$.consumedAt=Date.now()}function YR($){return{kind:"fork",source:$.source,through:$}}function VR($){return N4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function XR($){let Z=R4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return M0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function zR($){let Z=I8($),J;try{J=sN(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(V4("claude",V))continue;let X=rN(Z,Y),z;try{z=tN(X).mtimeMs}catch(H){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${H?.message??H}`)}Q.push({provider:"claude",sessionId:V,cwd:$,preview:GR(X),ts:z})}return Q.sort((Y,V)=>V.ts-Y.ts)}function HR($){let Z=$.slice().sort((Y,V)=>V.ts-Y.ts),J=Date.now()-eN,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(JR,Math.max(10,Q)))}function GR($){let Z="",J=null;try{J=aN($,"r");let Y=Buffer.alloc(65536),V=oN(J,Y,0,65536,0);Z=Y.subarray(0,V).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)nN(J)}let Q="";for(let Y of Z.split(`
271
+ `)){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 z=X.content.trim();if(z)return z.slice(0,80)}if(!Q&&X.type==="user"&&X.message){let z=WR(X.message);if(z)Q=z}}return Q.slice(0,80)}function WR($){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 Jj($,Z,J){if(!J){await b($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=VR($),Y=XR($),V=new Map,X=[];for(let K=0;K<Q.length;K++){let j=Q[K];if(K===0&&Y===null)continue;let _=hY(),D=K===0?Y:YR(Q[K-1].checkpoint);V.set(_,{kind:Z,launch:D,branchBase:Y,seedAnchors:Q.slice(0,K),writes:Q.slice(K).flatMap((P)=>P.writes)}),X.push({choiceId:_,preview:j.preview,ts:j.ts})}X.reverse();let z=Zj($,Z,J,V),H=hQ({projectName:k6($),panelId:z.id,mode:Z,entries:X}),G,W;try{G=await n($.chatId,H,(K)=>{W=K})}catch(K){throw r4($).delete(z.id),K}if(!G)r4($).delete(z.id),await I($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败
272
+ ${w(W)}`)}function Qj($,Z){return Jj($,"fork",Z)}function Yj($,Z){return Jj($,"back",Z)}async function Vj($,Z){if(!Z){await b($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():zR($.workDir)}catch(G){await I($.chatId,`❌ 历史会话读取失败: ${G instanceof Error?G.message:G}`);return}let Q=new Map,Y=HR(J).map((G)=>{let W=hY();return Q.set(W,{kind:"resume",launch:{kind:"fork",source:{provider:G.provider,sessionId:G.sessionId,cwd:G.cwd}},sourcePreview:G.preview,sourceTs:G.ts,sourceStatus:G.status}),{choiceId:W,preview:G.preview,ts:G.ts}}),V=Zj($,"resume",Z,Q),X=IQ({projectName:k6($),panelId:V.id,entries:Y}),z,H;try{z=await n($.chatId,X,(G)=>{H=G})}catch(G){throw r4($).delete(V.id),G}if(!z)r4($).delete(V.id),await I($.chatId,`❌ rs 历史列表发送失败
273
+ ${w(H)}`)}async function Xj($,Z){if(!Z){await b($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await b($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=eB(k6($));await b($.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{$j(J)}if(!Q.ok){await b($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await b($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function zj($){if(!X1($.sessionName)){await b($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await b($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await b($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await b($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function Hj($,Z,J,Q){let Y=IY($,"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 z=eB(V.baseName);B(`session-temp: fork ${$.sessionName} → ${z} (${X.launch.kind})`),await b($.chatId,`\uD83D\uDD31 正在分叉到 ${z}…`);let H;try{H=await $.opts.onCreateTempSession({chatName:z,userOpenId:Q,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{$j(z)}if(!H.ok)return{ok:!1,message:`分叉失败: ${H.error??"未知"}`};return{ok:!0,message:`已分叉到 ${z};原会话和磁盘文件未回滚`}}catch(z){return{ok:!1,message:`分叉失败: ${z instanceof Error?z.message:z}`}}finally{b6(V)}}async function Gj($,Z,J,Q){let Y=IY($,"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 z="";try{let W;if(!await n($.chatId,gQ({projectName:V.baseName,entries:X.writes}),(j)=>{W=j}))z=`;文件变更记录卡发送失败: ${w(W)}`}catch(W){z=`;文件变更记录卡发送失败: ${w(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:`回退失败;原会话绑定未改,请检查日志后重试${z}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${z}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${S0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${z}`}}catch(z){return{ok:!1,message:`回退失败: ${z instanceof Error?z.message:z}`}}finally{b6(V)}}async function Wj($,Z,J,Q){let Y=IY($,"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 b6(V),Error("resume panel contained a non-resume choice");let z=X.launch.source.sessionId,H=$.lastSessionId,G=(K,j)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:z,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:H,newSessionId:K,bindingState:j}),W=(K,j,_,D=null)=>({ok:K,message:j,resumePresentation:G(D,_)});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} ${z}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:H}:null}))return W(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return W(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let j=$.lastSessionId;if(!j)return W(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(j===z||H&&j===H)return W(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",j);return W(!0,"已创建并接入独立分支;源会话未修改","changed",j)}catch(K){return W(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{b6(V)}}var eN=86400000,$R=1800000,ZR=3600000,JR=40,rB,fY;var Kj=R(()=>{$0();M$();h();_4();D9();e1();rB=new WeakMap,fY=new Set});import{existsSync as Bj}from"node:fs";import{randomBytes as gY,timingSafeEqual as BR}from"node:crypto";import{isAbsolute as jR}from"node:path";function pY($,Z=new Set){if($ instanceof X4)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=pY(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return pY($.cause,Z);return null}function _R($){return $.itemId||$.turnId||"__latest__"}function jj($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function LR($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function PR($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function y6(){return m.runtime?.live_elapsed??"bucket"}function Pj($,Z){return`${$} (${p4(Date.now()-Z,y6()).label})`}function e4($){return $.length?$.map((Z)=>`${Z.operation}: ${w(Z)}`).join(`
274
+ `):w(void 0)}function MR($,Z){let J=Z?.apiMessage??Z?.message??"MISS";for(let Q of[Z?.cardId,Z?.elementId,Z?.targetElementId])if(Q)J=J.split(Q).join("<id>");return J=J.replace(/^cardkit\s+\S+\s+\S+\s+HTTP\s+\d+:\s*/i,"").replace(/\s+log_id=\S+/gi,"").replace(/\s+/g," ").trim(),`${$??"MISS"}:${Z?.httpStatus??"MISS"}:${J}`}var _j="Thinking...",qR="Writing...",DR="Working...",mY=1e4,w6=720000,FR=50,UR=256,v6=1e4,Lj=250,S$;var RY=R(()=>{D9();s9();_0();J1();tJ();_0();f0();JQ();ZY();z0();j0();g4();_4();G1();M$();$0();h();H0();EQ();J$();I4();_K();UJ();QY();MK();vK();tK();O6();$B();mJ();JB();KB();MB();CB();hB();gB();wY();tB();Kj();e1();S$=class S${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=gY(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??jK(),S$.all.add(this);let Q=tZ($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=C0(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=b1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=T4($);if(V)if(this.selectedProvider!=="claude")V$($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{M0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,z=this.lastSessionRef,H=!X&&z?.provider==="claude"&&z.cwd===this.workDir&&z.sessionId!==V.launch.source.sessionId&&z.sessionId!==V.previousSessionId;if(!X&&!H)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`session "${$}": restored ${H?"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:v.get(j$(this.proc)).name}:{}}}get workDir(){return uB(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 $Z(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?j$(this.proc):this.codexStartAccountOverride??v.selected(this.sessionName)}tokenSource($){let Z=C0($);return Z?.forAccount?G0($,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()===l?{}:{codexAccountId:this.codexAccountId()},...!$&&v.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=C0($.tokenSourceId);if($.codexAccountId&&!Z?.codexApiProvider)v.get($.codexAccountId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)V$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;if(this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=b1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,w1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId),!Z?.codexApiProvider){let J=$.codexAccountId??l;if($.codexAccountAutomatic)v.selectAuto(this.sessionName);else if(v.selected(this.sessionName)!==J)v.select(this.sessionName,J)}}dshEffortForSpawn(){if(O0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&I$($,this.selectedModel??$.defaultModel);if(!Z||!O0(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 w4({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!V4("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");let $=this.currentTokenSource();if(!$?.codexApiProvider&&!d9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(z)=>Z.spawnEnv(z):void 0,Q=new z4({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(z){V=z}let X=null;try{await Q.kill(2000)}catch(z){X=z}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${x(V)}; ${x(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=g8(this.workDir,$.sessionId);if(!Bj(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${S0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{let J=this.currentTokenSource();if(!J?.codexApiProvider&&!d9(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 z4({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(z)=>Q.spawnEnv(z):void 0,...Q?.codexApiProvider?{apiProvider:Q.codexApiProvider}:{}}),V=null;try{Z=await Y.readConversationRef($.sessionId)}catch(z){V=z,Z=$}let X=null;try{await Y.kill(2000)}catch(z){X=z}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${x(V)}; cleanup=${x(X)}`);if(V)throw V;if(X)throw X}return M0({kind:"resume",source:Z},this.selectedProvider,this.workDir),p9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...S$.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 _$(this.selectedEffort)?this.selectedEffort:M9}return M9}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&R0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=I$($,this.selectedModel??$.defaultModel);if(!R0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return T1}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??I$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?T1:M9)}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"?T1:M9);return{provider:Z,model:Q,effort:Y}}withModel($,Z){let J=this.modelLine(Z);return $.includes(J)?$:`${$} · ${J}`}async replaceFooterContent($,Z){let J;return{landed:await B0($,C.footer,this.footerElement(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}),failure:J}}footerElement($){return{tag:"markdown",element_id:C.footer,content:$.trim()||" "}}modelLine($=this.currentTurn??this.runtimeModelSelection()){return zQ($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return i0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(M0($.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=gY(32).toString("base64url");let Z={LODESTAR_AGENT_URL:c4(m.notify.bind,m.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"});M0(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(),z=G3({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:V?.id??null,...this.selectedProvider==="codex"?{codexAccountId:v.selected(this.sessionName)}:{},...Y?{codexAccountPreference:this.codexStartAccountOverride??v.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:g9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:d2},hostEnv:Z});return this.procSourceRevisions.set(z.process,z.sourceRevision),this.procFileDeliveryModes.set(z.process,X),z.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=C0(V),z=X?Z||null:$==="codex"?null:Z,H=X?J??I$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,z,H);let G=Y!==$?{anchors:N4(this.sessionName).slice(),base:R4(this.sessionName),pending:T4(this.sessionName)}:null;if(G)V$(this.sessionName,[],null,null);try{w1(this.sessionName,$,z,H,V)}catch(W){if(G)try{V$(this.sessionName,G.anchors,G.base,G.pending)}catch(K){throw AggregateError([W,K],`model selection write failed: ${x(W)}; conversation state restore failed: ${x(K)}`)}throw W}if(G)this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=V,this.selectedModel=z,this.selectedEffort=H,this.lastSessionRef=b1(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()===G4($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===G4($,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(G){X=G}V=await this.settleProcResumableState(Y);let z=this.finishProcStop(Y,X);this.opts.onLifecycleChange?.();let H=[...X?[X]:!z?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...V?[Error(V)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(x).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(x).join("; ")}`);return!0}startFooterTimer($,Z,J=(Q)=>Q){let Q=Date.now(),Y=Z,V=!1,X=!1,z=!1,H=!1,G=null,W=()=>{if(V)return;if(X){H=!0;return}X=!0,H=!1;let j=Y;this.replaceFooterContent($,J(Pj(Y,Q))).then((_)=>{if(X=!1,V)return;if(_.landed){if(H)W();return}if(z=!0,G)clearTimeout(G);if(G=null,H&&Y!==j)W()})},K=()=>{if(V||z)return;let{nextDelayMs:j}=p4(Date.now()-Q,y6());G=setTimeout(()=>{W(),K()},Math.max(1,Math.ceil(j)))};return W(),K(),{setStatus(j){if(j===Y)return;Y=j,W()},stop(){if(V=!0,G)clearTimeout(G)},elapsedSec(){return(Date.now()-Q)/1000}}}async openStatusCard($,Z,J="blue"){let Q=Date.now(),Y=xQ({sessionName:this.sessionName,title:$,status:Pj(Z,Q),template:J}),V,X=await n(this.chatId,Y,(H)=>{V=H});if(!X)return B(`session "${this.sessionName}": status card send failed title=${$}`),await I(this.chatId,`❌ 创建状态卡片失败: ${$}
275
+ ${w(V)}`),null;let z;try{z=await l$(X)}catch(H){return B(`session "${this.sessionName}": status card id_convert failed title=${$}: ${H}`),await I(this.chatId,`❌ 状态卡片初始化失败: ${$}
276
+ ${w(H)}`),null}return E$(z,1),{cardId:z,title:$,timer:this.startFooterTimer(z,Z,(H)=>U3($,H))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=U3($.title,`${Z} (${E0(J)})`);await v1($.cardId);let Y=[],V=(H)=>{Y.push(H)},X=await B0($.cardId,C.footer,this.footerElement(Q),{onFailure:V});a0($.cardId);let z=await k0($.cardId,b2({durationSec:J,suffix:Z}),V);if(X&&z)await q$($.cardId);else{let H=`footer=${X?"ok":"MISS"}, settings=${z?"ok":"MISS"}`;B(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await I(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}
277
+ ${e4(Y)}`)}}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&&BR(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?x(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 会话落盘确认失败: ${x(V)}`}let Q=$.conversationMaterializationFailure?.();if(Q&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${x(Q)}`;let Y=this.persistResumableSessionId(!1,$,!1);return[Z,Y].filter(Boolean).join(";")||null}resetFreshConversationState(){this.daemonRestoreRequired=!1,this.turnCounter=0,this.pendingConversationMaterialization=null,V$(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(v.get($),this.selectedProvider!=="codex"||this.currentTokenSource()?.codexApiProvider){if(this.proc?.isAlive())await this.stopUnlocked("切换到 Codex",{...Z,announce:!1});let Q=G0("codex-sub",$)?.defaultModel||null;V$(this.sessionName,[],null,null),w1(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=b1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")w1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&j$(this.proc)===$&&this.proc.turnRetry?.reason!=="quota")return Z.onStatus?.(`✅ 正在使用「${v.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 b(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&&!d9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){let W;if(!await n(this.chatId,n$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"}),(j)=>{W=j}))throw Error(`Codex 登录引导卡片发送失败:${w(W)}`)}return!1}if(!Bj(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await b(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{HJ(this.workDir)}catch(W){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${W}`),Z)await b(this.chatId,`❌ 创建项目失败: ${W}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Y;try{Y=this.spawnAgent()}catch(W){let K=`${this.backendLabel()} 启动失败: ${x(W)}`;if(B(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await b(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,Lj):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let z,H=null;try{Y.sendInitialize(),z=Y.initializationPromise?.()}catch(W){z=void 0,H=W}let G=H?{state:"error",error:H}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(z),()=>{B(`session "${this.sessionName}": codex init still pending after ${mY/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${V} init 确认`))});if(G.state==="error"||G.state==="exit"){let W=G.error?x(G.error):G.state;B(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${W}`);let j=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动失败: ${W}${j}`;if(J?.(_),Z)await b(this.chatId,_);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="timeout"){B(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${w6/1000}s)`);let K=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${V} 启动超时: ${w6/1000} 秒内初始化事务未完成${K}`;if(J?.(j),Z)await b(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Y||!Y.isAlive()){let W=`${V} 启动期间已退出`;if(B(`session "${this.sessionName}": ${W}`),J?.(`❌ ${W}`),Z)await b(this.chatId,`❌ ${W}`);return this.detachProc(Y),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 n(this.chatId,n$({phase:"checking",title:"等待额度恢复",message:"额度恢复后自动继续",hint:"stop 可取消等待"}));return!0}if(Z){let W=this.modelLine();await b(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),W].filter(Boolean).join(`
278
+ `))}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=(z,H)=>{if(Q)return;Q=!0,clearTimeout(V),clearTimeout(X),J({state:z,error:H})},V=setTimeout(()=>{if(Q)return;try{Z?.()}catch(z){Y("error",z)}},mY),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${w6/1000}s`))},w6);$.then(()=>Y("init"),(z)=>Y("error",z)),this.proc?.quotaWaitPromise?.().then(()=>Y("waiting_quota"),(z)=>Y("error",z))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(G,W)=>{if(Q)return;Q=!0,clearTimeout(V),$.off("init",X),$.off("error",z),$.off("exit",H),J({state:G,error:W})},V=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),z=(G)=>Y("error",G),H=(G)=>Y("exit",G);$.once("init",X),$.once("error",z),$.once("exit",H)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)g0($,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)g0(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;this.daemonRestoreRequired=!1;let Y=this.proc;if(Y)this.beginProcStop(Y);let V=null;try{await this.cancelAgentRuns($)}catch(F){V=F}if(!Y){if(this.status="stopped",this.opts.onLifecycleChange?.(),V)throw V;if(Q?.("⚪ session 当前未运行"),J)await b(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let X=this.persistResumableSessionId(!1,Y,!1),z=null;if(Q?.(`\uD83D\uDED1 停止 ${this.backendLabel(Y.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: ${x(F)}`)});let H=this.waitForTurnCloses().catch((F)=>B(`session "${this.sessionName}": stop main-card close failed: ${x(F)}`));this.beginProcStop(Y),this.status="stopped";let G=[];try{this.opts.onLifecycleChange?.()}catch(F){G.push(F),B(`session "${this.sessionName}": stop intent lifecycle write failed: ${x(F)}`)}let W=Y.conversationMaterializationBarrier?.();if(W){try{await W}catch(F){z=`Codex 会话落盘确认失败: ${x(F)}`}X=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 K=null;try{await Y.kill()}catch(F){K=F}let j=Y.conversationMaterializationFailure?.();if(j&&Y.isConversationResumable?.()!==!0)z=`Codex 会话落盘确认失败: ${x(j)}`;X=this.persistResumableSessionId(!1,Y,!1);let D=(await Promise.allSettled([this.resetBackgroundTasks(),H])).filter((F)=>F.status==="rejected").map((F)=>F.reason);for(let F of D)B(`session "${this.sessionName}": stop terminal cleanup failed: ${x(F)}`);let P=this.finishProcStop(Y,K);try{this.opts.onLifecycleChange?.()}catch(F){G.push(F),B(`session "${this.sessionName}": stop final lifecycle write failed: ${x(F)}`)}let L=[...V?[V]:[],...K?[K]:[],...!P&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...D,...G,...X?[Error(X)]:[],...z&&Y.isConversationResumable?.()!==!0?[Error(z)]:[]];if(L.length===1)throw L[0];if(L.length>1)throw AggregateError(L,`stop failed: ${L.map(x).join("; ")}`);if(Q?.(`✅ ${$}`),J)await b(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 b(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,k1(this.sessionName,null),this.pendingConversationMaterialization=null;let z=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),H=this.lastSessionRef;if($&&!z&&H?.cwd===null)try{H=await this.resolveLegacyResumeRef(H),this.lastSessionRef=H,this.lastSessionId=H.sessionId}catch(S){let g=this.invalidateMissingCodexResume(H.sessionId,S,J),V0=g?`❌ 旧会话不可恢复: ${x(S)};${g}`:`❌ 旧会话 cwd 校验失败: ${x(S)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Y?.(V0),Q)await b(this.chatId,V0);return!1}let G=H?.sessionId??null,W=z&&z.kind!=="fresh"?z.source.sessionId:G,K=W?S0(W):"",j=null,_=(S=this.proc)=>{if(!$||z||S?.provider!=="codex"||S.isConversationResumable?.()!==!0)return;j=this.persistResumableSessionId(!1,S,!1),H=this.lastSessionRef,G=H?.sessionId??null,W=G,K=W?S0(W):""},D=null;if(!Y&&Q&&$&&G){let S=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(D=await this.openStatusCard("restart",S),D)Y=(g)=>this.setStatusCard(D,g)}let P=Q&&!D,L=async(S)=>{if(D)await this.closeStatusCard(D,S)},F=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||lJ(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let S of this.fileDeliveries)S.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((S)=>{B(`session "${this.sessionName}": restart current main-card close failed: ${x(S)}`)});let U=this.waitForTurnCloses().catch((S)=>B(`session "${this.sessionName}": restart main-card close failed: ${x(S)}`)),A=null,M=null,O=null;if(this.proc){let S=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(S.provider)}`),O=S;let g=this.agentCapability;this.beginProcStop(S);try{await this.cancelAgentRuns("会话正在重启")}catch(c){M=c}let V0=S.conversationMaterializationBarrier?.();if(V0)try{await V0}catch(c){j=`Codex 会话落盘确认失败: ${x(c)}`}if(_(S),$&&!z&&j&&!M&&!F&&S.isAlive()){if(this.proc===S&&this.stoppingProc===S)this.stoppingProc=null,this.agentCapability=g;this.status=V;let c=`❌ ${this.backendLabel(S.provider)} 恢复点尚未安全落盘,已保留当前进程: ${j}`;if(B(`session "${this.sessionName}": abort restart before kill: ${j}`),Y?.(c),P)await b(this.chatId,c);return await L(c),!1}try{await S.kill()}catch(c){A=c}let e=S.conversationMaterializationFailure?.();if(e&&S.isConversationResumable?.()!==!0)j=`Codex 会话落盘确认失败: ${x(e)}`;_(S)}else try{await this.cancelAgentRuns("会话正在重启")}catch(S){M=S}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let k=(await Promise.allSettled([this.resetBackgroundTasks(),U])).filter((S)=>S.status==="rejected").map((S)=>S.reason);for(let S of k)B(`session "${this.sessionName}": restart terminal cleanup failed: ${x(S)}`);let E=O?this.finishProcStop(O,A):!0,f=[...M?[`agents=${x(M)}`]:[],...A?[`kill=${x(A)}`]:[],...!E&&!A?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...k.map((S)=>`cleanup=${x(S)}`),...j?[`resume=${j}`]:[]];if(f.length>0&&X)try{k1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(S){f.push(`pendingRestore=${x(S)}`)}if(f.length>0){let S=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${f.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(S),P)await b(this.chatId,S);return await L(S),!1}let d=z?.kind==="resume"||z?.kind==="fork";if($&&H||d){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let S;try{S=this.spawnAgent(H??void 0)}catch(p){let J0=`❌ ${this.backendLabel()} 恢复失败: ${x(p)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${x(p)}`),Y?.(J0),P)await b(this.chatId,J0);return this.status="stopped",this.opts.onLifecycleChange?.(),await L(J0),!1}this.attachProc(S);let g=this.backendLabel(),V0=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(S,Lj):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${g} 恢复启动`:`⏳ 等待 ${g} init 确认`);let e,c=null;try{S.sendInitialize(),e=S.initializationPromise?.()}catch(p){e=void 0,c=p}let N=c?{state:"error",error:c}:this.selectedProvider==="claude"?await V0:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(e),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${mY/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${g} init 确认 thread=${K}`))});if(N.state==="error"||N.state==="exit"||N.state==="timeout"){let p=N.state==="error"?this.invalidateMissingCodexResume(W,N.error,J):null,J0=[N.error?x(N.error):N.state,p].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${J0}`);let n1=await this.stopOwnedProc(S,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,X9=N.state==="timeout"?`❌ ${g} 恢复超时${n1}`:`❌ ${g} 恢复失败: ${J0}${n1}`;if(Y?.(X9),P)await b(this.chatId,X9);return this.status="stopped",this.opts.onLifecycleChange?.(),await L(X9),!1}if(this.proc!==S||!S.isAlive()){let p=`❌ ${g} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(p),P)await b(this.chatId,p);return this.detachProc(S),this.status="stopped",this.opts.onLifecycleChange?.(),await L(p),!1}let y=this.withModel(this.withWorktreeInstructionNotice(N.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&N.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Y?.(y),P)await b(this.chatId,y);if(this.status=N.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),N.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await L(y)}catch(p){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${x(p)}`),await I(this.chatId,`⚠️ ${y}
279
+ 状态卡收尾失败: ${x(p)}`)}return!0}else{if($&&!z){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),P)await b(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{M0($,this.selectedProvider,this.workDir);let J=T4(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)k1(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)k1(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{k1(this.sessionName,J),this.pendingConversationMaterialization=J}catch(V){throw AggregateError([Y,V],`fork start and pending-intent restore failed: ${x(Y)}; ${x(V)}`)}throw Y}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{M0($,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,z=N4(this.sessionName).slice(),H=R4(this.sessionName),G=T4(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,j=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,A4(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)p9(this.sessionName,X);else A4(this.sessionName,this.selectedProvider);V$(this.sessionName,z,H,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},_=!1;if(Q?.pendingLaunch)V$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,_=!0;this.pendingConversationLaunch=$;let D=(P)=>{K=X?.provider==="codex"&&X.sessionId===P};try{let P;try{P=$.kind==="fresh"?await this.restartUnlocked(!1,J,D):await this.restartUnlocked(!0,J,D)}catch(L){let F=null,U=this.proc&&this.proc!==Y?this.proc:null;if(U)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(T){F=T}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!F)F=Error("replacement process stop was not confirmed");let M=null;if(A)try{j()}catch(T){M=T}let O=[L,...F?[F]:[],...M?[M]:[]];if(O.length===1)throw L;throw AggregateError(O,`rollback launch and cleanup failed: ${O.map(x).join("; ")}`)}if(!P)return j(),!1;if(Q)try{if(!_)V$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(L){let F=null,U=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(T){F=T}let A=!U||this.proc!==U&&!U.isAlive();if(!A&&!F)F=Error("replacement process stop was not confirmed");let M=null;if(A)try{j()}catch(T){M=T}let O=[L,...F?[F]:[],...M?[M]:[]];if(O.length===1)throw L;throw AggregateError(O,`rollback branch commit failed: ${O.map(x).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){S$.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 aZ(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${x(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(...cQ(J.name,J.input));return Z}worktreeProjectName(){return g2(this)}worktreeProjectDir(){return t4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return dB(this,$)}delegatedAgentDeveloperInstructions($){return iB(this,$)}worktreeInstructionLoadedNotice(){return vY(this)}withWorktreeInstructionNotice($){return nB(this,$)}worktreeExtraInstruction(){return I3(this)}runWorktreeCommand($,Z){return aB(this,$,Z)}showWorktrees(){return yY(this)}showTasklistPanel(){return TB(this)}showAgentIdentityPanel($=""){return qB(this,$)}onAgentIdentityPage($,Z,J){return DB($,Z,J)}onTasklistEnable(){return EB(this)}onTasklistDeletePrompt($){return xB(this,$)}onTasklistDeleteConfirm($){return SB(this,$)}runCompactCommand(){return ZB(this)}showModelPanel(){return YB(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>UY(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=`模型设置已完成,但排队输入提交失败:${x($)}`;B(`session "${this.sessionName}": ${Z}`),await I(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Q=null){return this.runLifecycle("model-select",()=>WB(this,$,Z,J,Q))}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>NY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return OY(this,$,Z)}onModelPage($,Z,J){return N6(this,$,Z,J)}onModelAddOpen($,Z){return VB(this,$,Z)}onModelListEdit($,Z,J,Q){return this.runLifecycle("model-list-edit",()=>XB(this,$,Z,J,Q))}onModelPanelCancel($=""){return GB(this,$)}onModelCustomPrompt($,Z,J=""){return zB(this,$,Z,J)}consumeModelCustomMessage($,Z){return HB(this,$,Z)}onWorktreeDisband($){return sB(this,$)}showForkList($=""){return Qj(this,$)}showBackList($=""){return Yj(this,$)}showResumeList($=""){return Vj(this,$)}runBtwCommand($){return Xj(this,$)}runByeCommand(){return zj(this)}onForkSelect($,Z,J=""){return Hj(this,$,Z,J)}onBackSelect($,Z,J=""){return Gj(this,$,Z,J)}onResumeSelect($,Z,J=""){return Wj(this,$,Z,J)}runCommand($,Z="",J){return pG(this,$,Z,J)}getFileDeliveryMode(){return s4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return IB(this.chatId,this.sessionName,Z,$,{get:(J)=>s4.get(J,this.workDir),enable:(J,Q)=>s4.enable(J,this.workDir,Q),disable:(J)=>s4.disable(J,this.workDir),sendCard:(J,Q)=>n(this.chatId,J,Q),reportError:async(J)=>{if(B(`session "${this.sessionName}": ${J}`),!await b(this.chatId,J))throw Error(J)}},this.workDir)}async buildConsoleOpts($,Z){let J=await pW(),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:[...S$.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,accountUsages:await JY(),sysinfo:J}}async buildConsoleCard($){return z6(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await JY()}catch(Y){let V=x(Y);B(`console usage MISS: ${V}`),Z.accountUsages=[{id:"error",label:"额度",usage:{state:"network",windows:[],reason:V}}]}let J;if(!await B0($,C.consoleUsage,M3(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}))throw Error(`console usage element replace rejected: ${w(J)}`)}async mutateStaticCard($,Z,J){let Q=!0,Y=[];try{await J()}catch(X){Q=!1,Y.push(x(X)),B(`session "${this.sessionName}": ${Z} mutation failed: ${x(X)}`)}let V=!1;try{V=await k0($,{config:{streaming_mode:!1}},(X)=>{Y.push(w(X))})}catch(X){Y.push(w(X)),B(`session "${this.sessionName}": ${Z} streaming-off failed: ${x(X)}`)}if(!Q||!V)return B(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Q} streamingOff=${V} card=${$.slice(0,12)}`),await I(this.chatId,`⚠️ 卡片更新失败 (${Z})。
279
280
  ${Y.join(`
280
- `)||v(void 0)}`),!1;try{await q$($)}catch(X){return B(`session "${this.sessionName}": ${Z} dispose failed: ${S(X)}`),!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 v1($.cardId);let Y=[],V=(K)=>{Y.push(K)},X=await B0($.cardId,b.footer,Y6(Q,b.footer),{onFailure:V}),z=await A2($.cardId,Q6(Q),{type:"insert_after",targetElementId:b.footer,onFailure:V}),H=await A2($.cardId,V6(Q.sysinfo),{type:"insert_after",targetElementId:b.consoleProjects,onFailure:V}),G=await A2($.cardId,U3(Q),{type:"insert_after",targetElementId:b.consoleHost,onFailure:V});if(!X||!z||!H||!G){await I(this.chatId,`⚠️ 控制台卡片结构写入失败,请重新发送 hi。
281
- ${e4(Y)}`),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}if(a0($.cardId),!await k0($.cardId,C2({durationSec:J,suffix:Z}),V))await I(this.chatId,`⚠️ 控制台卡片状态写入失败。
282
- ${e4(Y)}`);this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleOpts(void 0);await i(this.chatId,X6($))}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 H=`❌ ${Q}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`;if(this.pendingTurnInputs=[],this.currentTurn)await this.closeTurnCard(H);else await k(this.chatId,H);return this.status="idle",!1}let Y=this.currentTurn,V=Y?Y.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),X=this.procFileDeliveryModes.get($),z=X===V?"":`${yB(V)}
283
-
284
- `;this.procFileDeliveryModes.set($,V),this.pendingUserMessageCount++;try{$.sendUserText(z+Z,[])}catch(H){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),X===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,X);throw H}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()}`,(W)=>this.withModel(W)),z=`\uD83D\uDE80 启动 ${this.backendLabel()}`,H=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(W)=>{z=W,X.setStatus(W)}});if(X.stop(),await v1(V.cardId),!H){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(z.startsWith("❌")?z:"❌ 启动失败",{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(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 k(this.chatId,`⚠️ ${Y} 本条消息未送给 Agent,请确认设置后重发。`);return}let V=this.disabledSubscriptionMessage();if(V){await k(this.chatId,`❌ ${V}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`);return}let X=this.blockedProcessMessage();if(X){await k(this.chatId,`❌ ${X}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await k(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 z=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(" ")+`
285
- `:"")+$,W=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let j=await X$(K,"OneSecond");if(!j)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,j);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,j);else g0(K,j)})().catch((j)=>{B(`session "${this.sessionName}": reaction tracking failed: ${S(j)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}await this.startColdUserTurn($,G,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}if(!this.openingTurn&&this.initCount>=1){let K=this.proc,j=this.procEpoch,_=this.beginTurnOpen(K,j);try{this.pendingTurnInputs.push($);let D=await this.openTurnCard(_,J,"user_message");if(!D||this.currentTurn!==D)return;if(this.proc!==K||this.procEpoch!==j||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,G))return;this.status="working"}finally{this.releaseTurnOpen(_)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}if(this.pendingTurnInputs.push($),!await this.sendClaimedUserText(this.proc,G))return;if(z&&Q)W(Q)}hasPendingAsk(){return hK(this)}refreshPendingAsks(){U6(this)}askBlockReason($){return a4(this,$)}onMultiMessageInbound($,Z,J,Q){return jK(this,$,Z,J,Q)}clearMultiMsgBuffer($){YY(this,$)}onAskMessageAnswer($,Z,J){return IK(this,$,Z,J)}onAskAnswer($,Z,J,Q){return gK(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return _Y(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return dK(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=b1(this.sessionName,"codex");if(A4(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=mY(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=b1(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{A4(this.sessionName,"codex")}catch(X){let z=`已确认恢复点无 rollout,但作废失败: ${S(X)}`;return B(`session "${this.sessionName}": ${z} thread=${$}`),z}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${S0($)}`;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 z=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${z.message}`),$)throw z;return z.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 z=Error(`Claude fork did not materialize an independent session id (${Y})`);if(B(`session "${this.sessionName}": ${z.message}`),$)throw z;return z.message}try{m9(this.sessionName,V)}catch(z){let H=`会话恢复点持久化失败: ${S(z)}`,G=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;if(B(`session "${this.sessionName}": ${H}`),$)throw z;if(G&&J)I(this.chatId,`⚠️ ${H};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return H}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let z=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(z&&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 k1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Q=`Claude 待生成分支标记清除失败: ${S(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(dJ(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=S($);if(B(`session "${this.sessionName}": task 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)=>D$(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: ${S(Z)}`)}if(await this.refreshBackgroundCardFull(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null,this.agentCards.releaseBackground(this.backgroundOwner),this.backgroundOwner=IY(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: ${S(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: ${S(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=(z,H)=>{$.on(z,(G)=>{if(!Q()){if(!Y)Y=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(z)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(z!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(z)} while process stop is pending`);return}H(G)})};X("error",(z)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${z}`)}),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 z=this.pendingUserMessageCount>0,H=!z&&this.bgResumePending;if(!z&&!H)return;let G=this.lastUserOpenId,W;try{W=this.beginTurnOpen($,J,!0)}catch(_){B(`session "${this.sessionName}": init turn-open ownership conflict: ${S(_)}`);return}if(this.bgResumePending=!1,z)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=z?[...this.currentBatchReactionIds.keys()]:[],j=()=>{for(let _ of K){let D=this.currentBatchReactionIds.get(_);if(this.currentBatchReactionIds.delete(_),D)g0(_,D)}};(async()=>{try{let _=await this.openTurnCard(W,G,z?"user_message":"bg_task_resume");if(!Q()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),_&&this.currentTurn===_)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);j();return}if(!_||this.currentTurn!==_){if(!this.ownsTurnOpen(W)){j();return}if(W.sawResult&&W.terminalSuffix)I(this.chatId,W.terminalSuffix);if(z)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),j();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((_)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${S(_)}`)})}),X("scheduled_turn_input",({text:z,promptId:H})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,z,H)}),X("conversation_materialized",({session_id:z,source:H})=>{if($.provider!=="codex")return;if($.sessionId!==z){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${z} current=${$.sessionId??"MISS"} source=${H}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${z} source=${H}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:z,source:H,error:G})=>{if($.provider!=="codex"||$.sessionId!==z)return;let W=`Codex 会话落盘确认失败,未写恢复点: ${S(G)}`,K=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,B(`session "${this.sessionName}": ${W} thread=${z} source=${H}`),K)I(this.chatId,`⚠️ ${W}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:z,diagnostics:H})=>{if(B(`session "${this.sessionName}": Codex account=${z}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),H.length)B(`session "${this.sessionName}": Codex 未参与选号的账号: ${H.join(";")}`)}),X("turn_started",({retry:z})=>{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(),z){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let H=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!H){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=H?{...H}:null,this.currentTurnUsageBaselineKnown=!0}),X("token_usage",({totalUsage:z})=>{if(this.persistResumableSessionId(),z)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(z)=>{this.handleTurnPlanUpdated(z)}),X("plan_delta",(z)=>{this.handlePlanDelta(z)}),X("context_compacted",(z)=>{this.handleContextCompacted(z)}),X("rate_limits_updated",(z)=>{if($.provider==="codex"&&!C0($.tokenSourceId)?.codexApiProvider)nX(z,j$($))}),X("thread_goal_updated",(z)=>{this.handleThreadGoalUpdated(z)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:z,parentToolUseId:H})=>{if(H)return;this.appendAssistant(z)}),X("assistant_block_stop",({parentToolUseId:z})=>{if(z)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:z,name:H,input:G,parentToolUseId:W})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(iJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,z,H,G)),this.onBackgroundTaskChanged();return}if(!W&&(H==="Task"||H==="Agent"||$.provider==="dsh"&&(H==="subagent"||H==="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(z,{confirmed:!1,input:G}),$.provider==="claude")this.lastMainTaskToolUseId=z,this.applyBgStore(X3(this.bgStore(),{task_id:z,tool_use_id:z,task_type:"subagent",description:G?.description||G?.name||"子 Agent",prompt:G?.prompt,subagent_type:G?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(cK(this,z,H,G),!W)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:z,content:H,is_error:G,parentToolUseId:W,input:K})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(aJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,z,H,G)),this.onBackgroundTaskChanged();return}let j=!W&&this.nativeAgentTools.get(z);if(j){if(this.nativeAgentTools.delete(z),this.lastMainTaskToolUseId===z)this.lastMainTaskToolUseId=null;if(G||$.provider==="claude"&&!j.confirmed&&j.input?.run_in_background!==!0){let _=typeof H==="string"?H:Array.isArray(H)?H.map((L)=>typeof L?.text==="string"?L.text:JSON.stringify(L)).join(`
286
- `):JSON.stringify(H)??"MISS",D=this.backgroundTasks.find((L)=>L.toolUseId===z);if(!D)this.applyBgStore(X3(this.bgStore(),{task_id:z,tool_use_id:z,task_type:"subagent",description:j.input?.description||"子 Agent",prompt:j.input?.prompt})),D=this.backgroundTasks.find((L)=>L.toolUseId===z);this.applyBgStore(v7(this.bgStore(),{task_id:D.id,status:G?"failed":"completed",summary:_})),this.onBackgroundTaskChanged(!0)}f2(this);return}lK(this,z,H,G,K)}),X("can_use_tool",(z)=>{iK(this,z)}),X("hook_callback",(z)=>{this.proc?.sendHookResponse(z.request_id,{})}),X("result",(z)=>{let H=this.persistResumableSessionId(),G=H?null:this.consumePendingConversationMaterialization(),W=[H,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 M=this.proc?.lastResult.subtype??"unknown",O=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${O} — ignored`),this.status="idle";return}let K=z?.is_error!==!0?this.recordTurnAnchor(z?.checkpoint):null;if(z?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let j=this.pendingMidTurnMsgs.length>0,_=this.proc?.lastResult.is_error===!0,D=this.proc?.lastResult.subtype??"success",L=typeof z?.error==="string"&&z.error.trim()?z.error.trim():D,P,F=!1,U=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),A=[W,K].filter(Boolean).join(";")||null;if(A)P=`⚠️ ${A}`,F=!0;else if(j)P=_?`⚠️ ${U} ${L},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(_)P=`⚠️ ${U} ${L}`,F=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=P,this.openingTurnOwner.terminalForcePush=F;if(A&&!this.currentTurn&&!this.openingTurn)I(this.chatId,`⚠️ ${A}`);if(B(`session "${this.sessionName}": SDK result subtype=${D} isError=${_} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${F}`),this.closeTurnCard(P,{forcePush:F,hasFreshResult:!0}).catch((M)=>{B(`session "${this.sessionName}": result card close failed: ${S(M)}`)}),this.status="idle",j)this.drainMidTurnAndOpen().catch((M)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${S(M)}`)})}),X("bg_task_started",(z)=>{let H=z.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,G=H?this.nativeAgentTools.get(H):void 0;if(G)G.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${z.task_id} type=${z.task_type??"-"} subagent=${z.subagent_type??"-"} toolUseId=${H?.slice(0,8)??"-"} desc=${(z.description??"").slice(0,40)}`),this.applyBgStore(X3(this.bgStore(),{...z,tool_use_id:H})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(z)=>{this.applyBgStore(lJ(this.bgStore(),z)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(z)=>{this.applyBgStore(uJ(this.bgStore(),z)),this.onBackgroundTaskChanged(!!z.patch.status||z.patch.is_backgrounded===!0)}),X("bg_task_settled",(z)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${z.task_id} status=${z.status}`),this.applyBgStore(v7(this.bgStore(),z)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(z)=>{this.applyBgStore(nJ(this.bgStore(),z.thread_id,z.item_id,z.tool,z.phase,z.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:z,signal:H,expected:G})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${z} signal=${H} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let D=$.conversationMaterializationFailure?.(),L=this.persistResumableSessionId(!1,$,!1),P=[D&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${S(D)}`:null,L].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((D)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${S(D)}`)});let W=this.backendLabel($.provider),K=`code=${z??"null"}, signal=${H??"null"}`,j=G?`\uD83D\uDED1 ${W} 已退出`:`⚠️ ${W} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(j).catch((D)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${S(D)}`)});let _=this.waitForTurnCloses().catch((D)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${S(D)}`)});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 D=await Promise.allSettled([_,this.resetBackgroundTasks()]);for(let L of D)if(L.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${S(L.reason)}`);if(!G)await k(this.chatId,`⚠️ ${W} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((D)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${S(D)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?y5(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=f5(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 I7(Z)}contextLimitForDisplay($=this.proc){return g7($?.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: ${S(Y)}`);return}let Q=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let H of Q)if(this.pendingTurnInputs.push(H.text),H.msgId){let G=this.pendingReactionIds.get(H.msgId)??"";this.currentBatchReactionIds.set(H.msgId,G),this.pendingReactionIds.delete(H.msgId)}let Y=Q.map((H)=>H.wireText).join(`
287
-
288
- `),X=Q[Q.length-1]?.userOpenId??this.lastUserOpenId,z=await this.openTurnCard(J,X,"user_message");if(!z||this.currentTurn!==z){for(let H of Q){if(!H.msgId)continue;let G=this.currentBatchReactionIds.get(H.msgId);if(this.currentBatchReactionIds.delete(H.msgId),G)g0(H.msgId,G)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let H of Q){if(!H.msgId)continue;let G=this.currentBatchReactionIds.get(H.msgId);if(this.currentBatchReactionIds.delete(H.msgId),G)g0(H.msgId,G)}this.status="stopped";return}try{if(!await this.sendClaimedUserText($,Y))return}catch(H){B(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${H}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await I(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${S(H)}。这批消息未开始处理,请重发。`),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=[],Y=(H)=>{Q.push(H)},V=J?await B0($,b.footer,this.footerElement(Z),{onFailure:Y}):!0;a0($);let X=await k0($,C2({suffix:Z}),Y);if(V&&X){await q$($);return}let z=`footer=${V?"ok":"MISS"}, settings=${X?"ok":"MISS"}`;B(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${z}`),await I(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${z})。
289
- ${e4(Q)}`)}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(),z=this.withModel(Q.initialFooter??"Waiting...(0s)",X),H=l7({sessionName:this.sessionName,turn:Y,provider:X.provider,model:X.model??void 0,effort:X.effort??"MISS",kind:J,userInputs:V,initialFooter:z,directStart:Q.directStart}),G,W=await i(this.chatId,H,(L)=>{G=L});if(!W){if(!this.ownsTurnOpen($))return null;if(B(`session "${this.sessionName}": openTurnCard sendCard failed — surfacing via raw text`),J==="user_message")await I(this.chatId,`❌ 创建对话卡片失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。
290
- ${v(G)}`);return null}let K;try{K=await l$(W)}catch(L){if(B(`session "${this.sessionName}": id_convert failed: ${L}`),J==="user_message"&&this.ownsTurnOpen($))await I(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。
291
- ${v(L)}`);return null}let j=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return E$(K,j),await this.terminalizeSupersededCard(K,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:K,...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(E$(K,j,(L,P)=>{this.onCardWriteFailure(_,K,L,P)}),this.currentTurn=_,Q.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let L=$.pendingCompactions.splice(0);B(`session "${this.sessionName}": replay ${L.length} context compaction event(s) buffered during card open`);for(let P of L)this.handleContextCompacted(P)}let D=this.takeOrphanAssistantText();if(D)this.appendAssistant(D),this.finalizeCurrentAssistantSegment();return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&r9($.cardId)<VR)return;this.startMidTurnRotate($)}reportCardWriteFailure($,Z,J,Q){let Y=zR(Z,J);if($.cardWriteFailureNotices.has(Y))return;$.cardWriteFailureNotices.add(Y);let V=J?.operation??"unknown operation",X=J?.elementId?` element=${J.elementId}`:"";I(this.chatId,`⚠️ 对话卡片写入失败(${V}${X})。${Q}同类错误本轮合并提示,完整诊断保留在日志。
292
- ${v({...J,code:Z})}`)}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(!v4(J,Q)){let X=Q?.operation??"unknown operation",z=Q?.elementId?` element=${Q.elementId}`:"";B(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${X}${z} code=${J??"n/a"} — not rotating`),this.reportCardWriteFailure(Y,J,Q,"未识别为卡片容量超限,未自动换卡;其余输出继续处理。");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,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(${Q.operation}, element=${Q.elementId??"MISS"});其余输出继续处理。
293
- ${v({...Q,code:J})}`);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,z)=>{if(!Y.value)Y.value={code:X,failure:z}};$.rotating=(async()=>{try{B(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${r9(Z)}`);let X=l7({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),z,H=await i(this.chatId,X,(P)=>{z=P});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,`⚠️ 续卡发送失败,后续内容到达时会再次尝试。
294
- ${v(z)}`);return}let G;try{G=await l$(H)}catch(P){if(B(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${P}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await I(this.chatId,`⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。
295
- ${v(P)}`);return}E$(G,2,(P,F)=>{if($.rotating){V(P,F);return}this.onCardWriteFailure($,G,P,F)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=G,$.cardRotationFailed=!1,$.messageId=H,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,j=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,K&&j){let P=b.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=P,$.currentAssistantText=j,$.segmentTexts.set(P,j)}if(j)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)T0($.cardId,w2(this.taskBoard),{type:"insert_before",targetElementId:b.footer});if($.planLiveInserted)T0($.cardId,W3($.planSteps,$.planExplanation,b.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?b.taskBoardLive:b.footer});for(let P of $.contextCompactionPending.values()){if(P.cardId!==Z)continue;P.cardId=G,P.created=!1,P.createFailure=void 0;let F=b.contextCompact(P.i);P.createPromise=f4(G,G3(P.i,P.notice,F),{type:"insert_before",targetElementId:w0($)}).then((U)=>{if(P.cardId===G)P.created=U.landed,P.createFailure=U.failure;return U.landed})}for(let[P,F]of _){if(K&&j&&P===K)continue;if(!y4(Z,P))continue;let U=$.assistantSegmentCount++,A=b.assistant(U);$.segmentTexts.set(A,F),await this.addCompletedAssistantSegment($,A,F)}qY(this,Z,G,J,Q,$),await v1(Z),qY(this,Z,G,J,Q,$);let D=new Set([b.taskBoardLive,b.planLive,...[...$.contextCompactionPending.values()].map((P)=>b.contextCompact(P.i))]);if(K)D.add(K);for(let P of J.values())if(P.output==null)D.add(b.tool(P.i));if(KG(Z).some((P)=>!D.has(P)))$.cardCapacityFailures.clear();await v1(G);try{await LY($,Z);let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await v1(Z);let F=$.mathRendered?.get(Z);for(let[w,T]of _){if(K&&j&&w===K)continue;if(y4(Z,w))continue;if(F?.has(w))continue;await F0(Z,w,this.completedAssistantElement(w,T))}let U=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",A=[],M=(w)=>{A.push(w)},O=await B0(Z,b.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${U}`)),{notifyCardFailure:!1,onFailure:M});a0(Z);let R=await k0(Z,C2({suffix:"\uD83D\uDCE8 转下一张"}),M);if(O&&R)await q$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${O} settings=${R}`),await I(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${O?"ok":"MISS"}, settings=${R?"ok":"MISS"}),本轮输出已续到新卡。
296
- ${e4(A)}`)}catch(P){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${P}`)}B(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${G.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=b.planUpdate($.planUpdateCount++);T0(Z,GQ($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:w0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=b.goalUpdate(Z.goalUpdateCount++);T0(Z.cardId,WQ($,J),{type:"insert_before",targetElementId:w0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=b.goalUpdate($.goalUpdateCount++);T0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
297
-
298
- 已清除`},{type:"insert_before",targetElementId:w0($)})}handleContextCompacted($){let Z=Xj($);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<w6){B(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((U)=>U.startsWith("turn:")),V=Q??Y,X=V?this.contextCompactionReceipts.get(V):void 0;if(Q&&!X&&$.phase!=="start"&&Y){let U=this.contextCompactionReceipts.get(Y);if(!U?.hasItemAlias&&U?.completed&&Date.now()-U.completedAt<w6||!U?.hasItemAlias&&U?.completionKey&&J?.contextCompactionCompleting.has(U.completionKey))V=Y,X=U,U.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,U)}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 z=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==z){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<w6){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let U=$R($);if(J.contextCompactionPending.has(U)||J.contextCompactionCompleted.has(U)){B(`session "${this.sessionName}": duplicate context compaction start ignored key=${U}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,z,!1);let A=J.contextCompactCount++,M=J.cardId,O=b.contextCompact(A),R={i:A,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};R.createPromise=f4(M,G3(A,$,O),{type:"insert_before",targetElementId:w0(J)}).then((w)=>{if(R.cardId===M)R.created=w.landed,R.createFailure=w.failure;return w.landed}),J.contextCompactionPending.set(U,R),B(`session "${this.sessionName}": context compaction start #${A+1} key=${U}`),h4(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<w6){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let H=$.itemId||$.turnId;if(H&&J.contextCompactionCompleted.has(H)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${H}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:ZR(J),W=G?J.contextCompactionPending.get(G):void 0,K=G??H??"__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 j=JR(W?.notice,$),_=J.contextCompactionEndOnly.get(K),D=W?.i??_??J.contextCompactCount++;if(!W&&_===void 0)J.contextCompactionEndOnly.set(K,D);J.contextCompactionCompleting.add(K);let L=[...new Set([...Xj(W?.notice??{}),...Z])];if(L.length>0)this.rememberContextCompactionReceipt(L,z,!1,K);let P=b.contextCompact(D),F=G3(D,j,P);B(`session "${this.sessionName}": context compaction completion write #${D+1} key=${K}`),(async()=>{let U=!1;if(!W)while(!0){let A=J.cardId;if(U=await A2(A,F,{type:"insert_before",targetElementId:w0(J)}),U)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==A)continue;break}else while(!0){let A=W.cardId;if(await W.createPromise,W.cardId!==A)continue;if(W.created)U=await B0(A,P,F);else{if(kJ(W.createFailure?.code,W.createFailure))BG(A,P),U=await B0(A,P,F,{notifyCardFailure:!1});if(!U)U=await A2(A,F,{type:"insert_before",targetElementId:w0(J)})}if(W.cardId!==A)continue;if(U){W.created=!0;break}let M=J.rotating;if(M){await M;continue}if(W.cardId!==A)continue;break}if(J.contextCompactionCompleting.delete(K),!U){B(`session "${this.sessionName}": context compaction completion write MISS #${D+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__",L.length>0){let A=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===K).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...L,...A])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${D+1} key=${K}`)})().catch((U)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${S(U)}`)}),h4(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>XR){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,z]of this.contextCompactionReceipts)if(z===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?b.taskBoardLive:b.footer;Z.planLiveInserted=!0,T0(Z.cardId,W3(Z.planSteps,Z.planExplanation,b.planLive),{type:"insert_before",targetElementId:J})}else B0(Z.cardId,b.planLive,W3(Z.planSteps,Z.planExplanation,b.planLive),{notifyCardFailure:!1});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&&c7(Z)===c7(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=b.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);h4(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
299
-
300
- `).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 (${$})`),k(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
301
-
302
- ${J}`)}completedAssistantElement($,Z){if(HY(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 TK(Q);if(!await B0(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=w0($),V=(async()=>{if(!await A2(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(HY(J)){let z=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((H)=>B(`session "${this.sessionName}": math render ${Z} failed: ${H}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(z),z.finally(()=>$.mathRenderInflight?.get(Q)?.delete(z))}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 原始回复:
303
-
304
- ${J}`;if(!await k(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 HK($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return J0($)}sendOutboundPath($,Z){let J=L6($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!eN(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),l9(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: ${S(Y)}`),k(this.chatId,`❌ 文件交付失败:${S(Y)}`)}}createFileDeliveryForTurn($){return SB({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($.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Q=()=>{if($.footerStatusLabel!==Z)return;let V=$.cardId;if($.footerStatusWriteCardId===V){$.footerStatusPendingRender=Q;return}$.footerStatusPendingRender=void 0;let{label:X}=p4(Date.now()-$.footerStatusStartedAt,v6()),z=Z===zj?this.proc?.lastThinkingTokens:null,H=typeof z==="number"?` · 约 ${z} tokens`:"";$.footerStatusWriteCardId=V,this.replaceFooterContent(V,this.withModel(`${Z}${H} (${X})`)).then((G)=>{if($.footerStatusWriteCardId===V)$.footerStatusWriteCardId=void 0;if($.cardId!==V||$.footerStatusLabel===null)return;if(G.landed){let K=$.footerStatusPendingRender;$.footerStatusPendingRender=void 0,K?.();return}if($.footerStatusFailedCardId=V,$.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null;let W=$.footerStatusPendingRender;if($.footerStatusPendingRender=void 0,$.footerStatusLabel!==Z)W?.()})},Y=()=>{if($.footerStatusLabel!==Z||$.footerStatusFailedCardId===$.cardId)return;let{nextDelayMs:V}=p4(Date.now()-$.footerStatusStartedAt,v6());$.footerStatusHandle=setTimeout(()=>{Q(),Y()},Math.max(1,Math.ceil(V)))};Q(),Y()}startThinkingFooter($){this.startFooterStatus($,zj)}startWritingFooter($){this.startFooterStatus($,QR)}startWorkingFooter($){this.startFooterStatus($,YR)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null,$.footerStatusPendingRender=void 0}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 z=X.windows.find((G)=>G.kind==="fiveHour");if(Q.kind==="claude-subscription"){let G=yH(X,V),W={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(z??W,G??W)}let H=X.windows.find((G)=>G.kind==="weekly");if(z||H)return this.fmtDualWindowSuffix(z??null,H??null)}return` | ${xQ(X)}`}if($==="codex"){let X=Y??(Z?.provider==="codex"?a5(j$(Z)):null);if(!X)return" | 额度 MISS";let z=X.read();if(!z)return" | 额度 MISS";let H=W1(z.credits);return this.fmtDualWindowSuffix(z.fiveHour,z.weekly)+(H?` · ${H}`:"")}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()?u$(V.resetsAt):"",z=`${Math.round(V.percent)}%`;return X?`${X}·${z}`:z},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(S).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)g0(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"?G0(Q.tokenSourceId??this.selectedTokenSourceId,j$(Q)):this.currentTokenSource(),codexUsage:Q?.provider==="codex"&&!C0(Q.tokenSourceId)?.codexApiProvider?a5(j$(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 LY(Q),Q.fileDelivery)try{for(let O of await Q.fileDelivery.finish())Q.outboundSentPaths.add(O)}catch(O){B(`session "${this.sessionName}": file delivery close failed: ${S(O)}`),await I(this.chatId,`❌ 文件交付收尾失败:${S(O)}`)}finally{this.fileDeliveries.delete(Q.fileDelivery)}this.stopFooterStatus(Q);let Y=(Date.now()-Q.startedAt)/1000,V=Q.cardId,X=Q.segmentTexts;await v1(V);let z=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:O,currentAssistantText:R}=Q;if(!await this.addCompletedAssistantSegment(Q,O,R))z.set(O,R);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let H=Q.assistantWriteInflight?.get(V);if(H?.size)await Promise.allSettled([...H]);let G=Q.mathRenderInflight?.get(V);if(G?.size)await Promise.allSettled([...G]);let W=Q.mathRendered?.get(V);for(let[O,R]of X){if(y4(V,O)){z.set(O,R);continue}if(W?.has(O))continue;await F0(V,O,this.completedAssistantElement(O,R))}if(Q.cardRotationFailed)for(let[O,R]of X)z.set(O,R);let K=Z?Z:"✅",j=[`${K} ⏱ ${E0(Y)}`];if(J.hasFreshResult){let{contextTokens:O,contextLimit:R}=$,w=Q.provider==="claude",T=zQ(O,R,w?0:void 0);if(T)j.push(`\uD83E\uDDE0 ${T}`);let f=$.lastTurnDelta?.costUsd??0;if(f>0)j.push(`\uD83D\uDCB0 $${f.toFixed(3)}`)}if(Q.contextCompactCount>0)j.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)j.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let _=this.modelLine(Q);if(_)j.push(_);let D=j.join(" | "),L=J.hasFreshResult?HQ($.lastTurnUsage)+(Q.cardRotationFailed?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Q.model)):"",P=L?`${D}
305
- ${L}`:D,F=[],U=(O)=>{F.push(O)},A=await B0(V,b.footer,this.footerElement(P),{onFailure:U});a0(V);let M=await k0(V,C2({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}),U);if(A&&M)await q$(V);else{let O=`footer=${A?"ok":"MISS"}, settings=${M?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${O}`),await I(this.chatId,`⚠️ 对话卡片终态写入失败 (${O})。本轮已结束: ${K}
306
- ${e4(F)}`)}for(let O of z.values())await this.sendAssistantTextFallback(O,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.cardRotationFailed)L2(Q.messageId,[Q.userOpenId])}}});function O$($){return{card:{type:"raw",data:$}}}import{randomUUID as HR}from"node:crypto";function pY($){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(j$($.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:d0().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 Wj($,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[z,H]of Object.entries(V.value)){if(!WR.has(z))throw Error(`unsupported model action field: ${z}`);if(z==="page"){if(typeof H!=="number"||!Number.isSafeInteger(H)||H<0)throw Error("invalid page");X.page=H}else{if(typeof H!=="string"||!H.trim()||H.length>1024)throw Error(`invalid ${z}`);X[z]=H.trim()}}if(!GR.has(String(X.kind)))throw Error("only model panel actions are supported");for(let z of["panel_id","source_id"])if(!X[z])throw Error(`${z} 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&&!g$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${HR()}`,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 GR,WR;var Kj=N(()=>{_0();X0();j0();GR=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"]),WR=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as KR}from"node:http";import{randomUUID as BR}from"node:crypto";function _j($){if($.allowReply&&$.buttons?.length)throw Error(jj);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 H of $.images??[])if(H.key)X.push({tag:"img",img_key:H.key,alt:{tag:"plain_text",content:"screenshot"}});else{let G=H.error?`
307
- ${J0(H.error)}`:"";X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${H.src}${G}</font>`})}if(X.push({tag:"markdown",content:SZ($.text??"")||"_(空消息)_"}),$.resolution){let H=$.resolution,G=H.kind==="text"?"已回复":`已选择:${H.text}`,W;if(H.status==="processing")W=`<font color='blue'>⏳ ${G} · 推送中…</font>`;else if(H.status==="failed")W=`<font color='red'>⚠️ ${H.kind==="text"?G:`已选:${H.text}`} · 回调失败:${J0(H.detail??"未知")} · ${V}</font>`;else if(H.status==="delivered")W=`<font color='green'>✅ ${G} · 反馈已送达 · ${V}</font>`;else if(H.status==="unknown")W=`<font color='red'>⚠️ ${G} · 送达状态未知,禁止自动重试 · ${V}</font>`;else W=`<font color='green'>✅ ${G} · ${V}</font>`;if(X.push({tag:"markdown",content:W}),H.status==="delivered"&&H.reply)X.push({tag:"markdown",content:J0(H.reply)})}let z=Q&&(!$.resolution||$.resolution.status==="failed");if(z&&$.buttons?.length)X.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((H)=>({tag:"button",text:{tag:"plain_text",content:H.text},type:H.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:H.id}}]}))}]});if(X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${V}</font>`}),z&&$.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 l1($,Z,J){let Q=J?.status??Z.status,Y={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${J0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:J0(Z.response.text)});if(Q==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
308
- 你的下一条文字优先用于这条通知,完成后再回答 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'>${J0(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:J0(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 LR($){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(!PR.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>Bj)return{error:`button "${Y}" text > ${Bj} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let X=String(Q.type??"default").toLowerCase(),z=_R.has(X)?X:"default";J.push({id:Y,text:V,type:z})}return{buttons:J}}function qR($){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 Pj($){try{let Z=KR((J,Q)=>{Promise.resolve().then(async()=>{let V;try{V=new URL(J.url??"/","http://localhost")}catch{Q.statusCode=400,Q.end("bad request URL");return}if(!await $.extraHandler?.(J,Q,V))await DR(J,Q)}).catch((V)=>{if(B(`notify: handler crash: ${V?.message??V}`),!Q.headersSent)Q.statusCode=500,Q.setHeader("content-type","text/plain; charset=utf-8"),Q.end(V instanceof y0?v(V):"internal error");else try{Q.end()}catch{}})});return 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`)}),Z}catch(Z){B(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function DR($,Z,J=Z0){let Q=new URL($.url??"/","http://localhost"),Y=(E,x)=>{Z.statusCode=E,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(x)},V=(E,x)=>{Z.statusCode=E,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(x))};if($.method==="GET"&&Q.pathname==="/")return Y(200,`lodestar notify
281
+ `)||w(void 0)}`),!1;try{await q$($)}catch(X){return B(`session "${this.sessionName}": ${Z} dispose failed: ${x(X)}`),!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 v1($.cardId);let Y=[],V=(K)=>{Y.push(K)},X=await B0($.cardId,C.footer,V6(Q,C.footer),{onFailure:V}),z=await N2($.cardId,Y6(Q),{type:"insert_after",targetElementId:C.footer,onFailure:V}),H=await N2($.cardId,X6(Q.sysinfo),{type:"insert_after",targetElementId:C.consoleProjects,onFailure:V}),G=await N2($.cardId,M3(Q),{type:"insert_after",targetElementId:C.consoleHost,onFailure:V});if(!X||!z||!H||!G){await I(this.chatId,`⚠️ 控制台卡片结构写入失败,请重新发送 hi。
282
+ ${e4(Y)}`),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}if(a0($.cardId),!await k0($.cardId,b2({durationSec:J,suffix:Z}),V))await I(this.chatId,`⚠️ 控制台卡片状态写入失败。
283
+ ${e4(Y)}`);this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleOpts(void 0);await n(this.chatId,z6($))}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 H=`❌ ${Q}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`;if(this.pendingTurnInputs=[],this.currentTurn)await this.closeTurnCard(H);else await b(this.chatId,H);return this.status="idle",!1}let Y=this.currentTurn,V=Y?Y.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),X=this.procFileDeliveryModes.get($),z=X===V?"":`${cB(V)}
284
+
285
+ `;this.procFileDeliveryModes.set($,V),this.pendingUserMessageCount++;try{$.sendUserText(z+Z,[])}catch(H){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),X===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,X);throw H}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()}`,(W)=>this.withModel(W)),z=`\uD83D\uDE80 启动 ${this.backendLabel()}`,H=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(W)=>{z=W,X.setStatus(W)}});if(X.stop(),await v1(V.cardId),!H){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(z.startsWith("❌")?z:"❌ 启动失败",{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(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 b(this.chatId,`⚠️ ${Y} 本条消息未送给 Agent,请确认设置后重发。`);return}let V=this.disabledSubscriptionMessage();if(V){await b(this.chatId,`❌ ${V}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`);return}let X=this.blockedProcessMessage();if(X){await b(this.chatId,`❌ ${X}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.daemonRestoreRequired){await b(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 z=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(" ")+`
286
+ `:"")+$,W=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let j=await X$(K,"OneSecond");if(!j)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,j);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,j);else g0(K,j)})().catch((j)=>{B(`session "${this.sessionName}": reaction tracking failed: ${x(j)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}await this.startColdUserTurn($,G,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}if(!this.openingTurn&&this.initCount>=1){let K=this.proc,j=this.procEpoch,_=this.beginTurnOpen(K,j);try{this.pendingTurnInputs.push($);let D=await this.openTurnCard(_,J,"user_message");if(!D||this.currentTurn!==D)return;if(this.proc!==K||this.procEpoch!==j||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,G))return;this.status="working"}finally{this.releaseTurnOpen(_)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:G,userOpenId:J,msgId:Q}),Q)W(Q);return}if(this.pendingTurnInputs.push($),!await this.sendClaimedUserText(this.proc,G))return;if(z&&Q)W(Q)}hasPendingAsk(){return uK(this)}refreshPendingAsks(){M6(this)}askBlockReason($){return a4(this,$)}onMultiMessageInbound($,Z,J,Q){return UK(this,$,Z,J,Q)}clearMultiMsgBuffer($){VY(this,$)}onAskMessageAnswer($,Z,J){return dK(this,$,Z,J)}onAskAnswer($,Z,J,Q){return iK(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return LY(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return rK(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=b1(this.sessionName,"codex");if(A4(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=pY(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=b1(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{A4(this.sessionName,"codex")}catch(X){let z=`已确认恢复点无 rollout,但作废失败: ${x(X)}`;return B(`session "${this.sessionName}": ${z} thread=${$}`),z}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${S0($)}`;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 z=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${z.message}`),$)throw z;return z.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 z=Error(`Claude fork did not materialize an independent session id (${Y})`);if(B(`session "${this.sessionName}": ${z.message}`),$)throw z;return z.message}try{p9(this.sessionName,V)}catch(z){let H=`会话恢复点持久化失败: ${x(z)}`,G=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;if(B(`session "${this.sessionName}": ${H}`),$)throw z;if(G&&J)I(this.chatId,`⚠️ ${H};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return H}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let z=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(z&&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 k1(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Q=`Claude 待生成分支标记清除失败: ${x(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(iJ(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=x($);if(B(`session "${this.sessionName}": task 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)=>D$(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: ${x(Z)}`)}if(await this.refreshBackgroundCardFull(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null,this.agentCards.releaseBackground(this.backgroundOwner),this.backgroundOwner=gY(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: ${x(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: ${x(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=(z,H)=>{$.on(z,(G)=>{if(!Q()){if(!Y)Y=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(z)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(z!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(z)} while process stop is pending`);return}H(G)})};X("error",(z)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${z}`)}),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 z=this.pendingUserMessageCount>0,H=!z&&this.bgResumePending;if(!z&&!H)return;let G=this.lastUserOpenId,W;try{W=this.beginTurnOpen($,J,!0)}catch(_){B(`session "${this.sessionName}": init turn-open ownership conflict: ${x(_)}`);return}if(this.bgResumePending=!1,z)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=z?[...this.currentBatchReactionIds.keys()]:[],j=()=>{for(let _ of K){let D=this.currentBatchReactionIds.get(_);if(this.currentBatchReactionIds.delete(_),D)g0(_,D)}};(async()=>{try{let _=await this.openTurnCard(W,G,z?"user_message":"bg_task_resume");if(!Q()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),_&&this.currentTurn===_)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);j();return}if(!_||this.currentTurn!==_){if(!this.ownsTurnOpen(W)){j();return}if(W.sawResult&&W.terminalSuffix)I(this.chatId,W.terminalSuffix);if(z)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),j();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((_)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${x(_)}`)})}),X("scheduled_turn_input",({text:z,promptId:H})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,z,H)}),X("conversation_materialized",({session_id:z,source:H})=>{if($.provider!=="codex")return;if($.sessionId!==z){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${z} current=${$.sessionId??"MISS"} source=${H}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${z} source=${H}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:z,source:H,error:G})=>{if($.provider!=="codex"||$.sessionId!==z)return;let W=`Codex 会话落盘确认失败,未写恢复点: ${x(G)}`,K=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,B(`session "${this.sessionName}": ${W} thread=${z} source=${H}`),K)I(this.chatId,`⚠️ ${W}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:z,diagnostics:H})=>{if(B(`session "${this.sessionName}": Codex account=${z}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),H.length)B(`session "${this.sessionName}": Codex 未参与选号的账号: ${H.join(";")}`)}),X("turn_started",({retry:z})=>{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(),z){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let H=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!H){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=H?{...H}:null,this.currentTurnUsageBaselineKnown=!0}),X("token_usage",({totalUsage:z})=>{if(this.persistResumableSessionId(),z)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(z)=>{this.handleTurnPlanUpdated(z)}),X("plan_delta",(z)=>{this.handlePlanDelta(z)}),X("context_compacted",(z)=>{this.handleContextCompacted(z)}),X("rate_limits_updated",(z)=>{if($.provider==="codex"&&!C0($.tokenSourceId)?.codexApiProvider)$z(z,j$($))}),X("thread_goal_updated",(z)=>{this.handleThreadGoalUpdated(z)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:z,parentToolUseId:H})=>{if(H)return;this.appendAssistant(z)}),X("assistant_block_stop",({parentToolUseId:z})=>{if(z)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:z,name:H,input:G,parentToolUseId:W})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(nJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,z,H,G)),this.onBackgroundTaskChanged();return}if(!W&&(H==="Task"||H==="Agent"||$.provider==="dsh"&&(H==="subagent"||H==="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(z,{confirmed:!1,input:G}),$.provider==="claude")this.lastMainTaskToolUseId=z,this.applyBgStore(z3(this.bgStore(),{task_id:z,tool_use_id:z,task_type:"subagent",description:G?.description||G?.name||"子 Agent",prompt:G?.prompt,subagent_type:G?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(oK(this,z,H,G),!W)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:z,content:H,is_error:G,parentToolUseId:W,input:K})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(oJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,z,H,G)),this.onBackgroundTaskChanged();return}let j=!W&&this.nativeAgentTools.get(z);if(j){if(this.nativeAgentTools.delete(z),this.lastMainTaskToolUseId===z)this.lastMainTaskToolUseId=null;if(G||$.provider==="claude"&&!j.confirmed&&j.input?.run_in_background!==!0){let _=typeof H==="string"?H:Array.isArray(H)?H.map((P)=>typeof P?.text==="string"?P.text:JSON.stringify(P)).join(`
287
+ `):JSON.stringify(H)??"MISS",D=this.backgroundTasks.find((P)=>P.toolUseId===z);if(!D)this.applyBgStore(z3(this.bgStore(),{task_id:z,tool_use_id:z,task_type:"subagent",description:j.input?.description||"子 Agent",prompt:j.input?.prompt})),D=this.backgroundTasks.find((P)=>P.toolUseId===z);this.applyBgStore(y7(this.bgStore(),{task_id:D.id,status:G?"failed":"completed",summary:_})),this.onBackgroundTaskChanged(!0)}h2(this);return}sK(this,z,H,G,K)}),X("can_use_tool",(z)=>{eK(this,z)}),X("hook_callback",(z)=>{this.proc?.sendHookResponse(z.request_id,{})}),X("result",(z)=>{let H=this.persistResumableSessionId(),G=H?null:this.consumePendingConversationMaterialization(),W=[H,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 M=this.proc?.lastResult.subtype??"unknown",O=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${M} isError=${O} — ignored`),this.status="idle";return}let K=z?.is_error!==!0?this.recordTurnAnchor(z?.checkpoint):null;if(z?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let j=this.pendingMidTurnMsgs.length>0,_=this.proc?.lastResult.is_error===!0,D=this.proc?.lastResult.subtype??"success",P=typeof z?.error==="string"&&z.error.trim()?z.error.trim():D,L,F=!1,U=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),A=[W,K].filter(Boolean).join(";")||null;if(A)L=`⚠️ ${A}`,F=!0;else if(j)L=_?`⚠️ ${U} ${P},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(_)L=`⚠️ ${U} ${P}`,F=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=L,this.openingTurnOwner.terminalForcePush=F;if(A&&!this.currentTurn&&!this.openingTurn)I(this.chatId,`⚠️ ${A}`);if(B(`session "${this.sessionName}": SDK result subtype=${D} isError=${_} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${F}`),this.closeTurnCard(L,{forcePush:F,hasFreshResult:!0}).catch((M)=>{B(`session "${this.sessionName}": result card close failed: ${x(M)}`)}),this.status="idle",j)this.drainMidTurnAndOpen().catch((M)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${x(M)}`)})}),X("bg_task_started",(z)=>{let H=z.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,G=H?this.nativeAgentTools.get(H):void 0;if(G)G.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${z.task_id} type=${z.task_type??"-"} subagent=${z.subagent_type??"-"} toolUseId=${H?.slice(0,8)??"-"} desc=${(z.description??"").slice(0,40)}`),this.applyBgStore(z3(this.bgStore(),{...z,tool_use_id:H})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(z)=>{this.applyBgStore(uJ(this.bgStore(),z)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(z)=>{this.applyBgStore(dJ(this.bgStore(),z)),this.onBackgroundTaskChanged(!!z.patch.status||z.patch.is_backgrounded===!0)}),X("bg_task_settled",(z)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${z.task_id} status=${z.status}`),this.applyBgStore(y7(this.bgStore(),z)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(z)=>{this.applyBgStore(aJ(this.bgStore(),z.thread_id,z.item_id,z.tool,z.phase,z.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:z,signal:H,expected:G})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${z} signal=${H} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let D=$.conversationMaterializationFailure?.(),P=this.persistResumableSessionId(!1,$,!1),L=[D&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${x(D)}`:null,P].filter(Boolean).join(";");if(L)I(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${L}`);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((D)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${x(D)}`)});let W=this.backendLabel($.provider),K=`code=${z??"null"}, signal=${H??"null"}`,j=G?`\uD83D\uDED1 ${W} 已退出`:`⚠️ ${W} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(j).catch((D)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${x(D)}`)});let _=this.waitForTurnCloses().catch((D)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${x(D)}`)});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 D=await Promise.allSettled([_,this.resetBackgroundTasks()]);for(let P of D)if(P.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${x(P.reason)}`);if(!G)await b(this.chatId,`⚠️ ${W} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((D)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${x(D)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?f5(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=h5(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 g7(Z)}contextLimitForDisplay($=this.proc){return m7($?.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: ${x(Y)}`);return}let Q=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let H of Q)if(this.pendingTurnInputs.push(H.text),H.msgId){let G=this.pendingReactionIds.get(H.msgId)??"";this.currentBatchReactionIds.set(H.msgId,G),this.pendingReactionIds.delete(H.msgId)}let Y=Q.map((H)=>H.wireText).join(`
288
+
289
+ `),X=Q[Q.length-1]?.userOpenId??this.lastUserOpenId,z=await this.openTurnCard(J,X,"user_message");if(!z||this.currentTurn!==z){for(let H of Q){if(!H.msgId)continue;let G=this.currentBatchReactionIds.get(H.msgId);if(this.currentBatchReactionIds.delete(H.msgId),G)g0(H.msgId,G)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let H of Q){if(!H.msgId)continue;let G=this.currentBatchReactionIds.get(H.msgId);if(this.currentBatchReactionIds.delete(H.msgId),G)g0(H.msgId,G)}this.status="stopped";return}try{if(!await this.sendClaimedUserText($,Y))return}catch(H){B(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${H}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await I(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${x(H)}。这批消息未开始处理,请重发。`),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=[],Y=(H)=>{Q.push(H)},V=J?await B0($,C.footer,this.footerElement(Z),{onFailure:Y}):!0;a0($);let X=await k0($,b2({suffix:Z}),Y);if(V&&X){await q$($);return}let z=`footer=${V?"ok":"MISS"}, settings=${X?"ok":"MISS"}`;B(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${z}`),await I(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${z})。
290
+ ${e4(Q)}`)}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(),z=this.withModel(Q.initialFooter??"Waiting...(0s)",X),H=u7({sessionName:this.sessionName,turn:Y,provider:X.provider,model:X.model??void 0,effort:X.effort??"MISS",kind:J,userInputs:V,initialFooter:z,directStart:Q.directStart}),G,W=await n(this.chatId,H,(P)=>{G=P});if(!W){if(!this.ownsTurnOpen($))return null;if(B(`session "${this.sessionName}": openTurnCard sendCard failed — surfacing via raw text`),J==="user_message")await I(this.chatId,`❌ 创建对话卡片失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。
291
+ ${w(G)}`);return null}let K;try{K=await l$(W)}catch(P){if(B(`session "${this.sessionName}": id_convert failed: ${P}`),J==="user_message"&&this.ownsTurnOpen($))await I(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。
292
+ ${w(P)}`);return null}let j=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(V.length>0?1:0)+1;if(!this.ownsTurnOpen($))return E$(K,j),await this.terminalizeSupersededCard(K,"⚠️ 会话已切换,本卡已作废",!0),null;let _={cardId:K,...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(E$(K,j,(P,L)=>{this.onCardWriteFailure(_,K,P,L)}),this.currentTurn=_,Q.startThinking!==!1)this.startThinkingFooter(_);if($.pendingCompactions.length>0){let P=$.pendingCompactions.splice(0);B(`session "${this.sessionName}": replay ${P.length} context compaction event(s) buffered during card open`);for(let L of P)this.handleContextCompacted(L)}let D=this.takeOrphanAssistantText();if(D)this.appendAssistant(D),this.finalizeCurrentAssistantSegment();return _}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&e9($.cardId)<FR)return;this.startMidTurnRotate($)}reportCardWriteFailure($,Z,J,Q){let Y=MR(Z,J);if($.cardWriteFailureNotices.has(Y))return;$.cardWriteFailureNotices.add(Y);let V=J?.operation??"unknown operation",X=J?.elementId?` element=${J.elementId}`:"";I(this.chatId,`⚠️ 对话卡片写入失败(${V}${X})。${Q}同类错误本轮合并提示,完整诊断保留在日志。
293
+ ${w({...J,code:Z})}`)}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(!v4(J,Q)){let X=Q?.operation??"unknown operation",z=Q?.elementId?` element=${Q.elementId}`:"";B(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${X}${z} code=${J??"n/a"} — not rotating`),this.reportCardWriteFailure(Y,J,Q,"未识别为卡片容量超限,未自动换卡;其余输出继续处理。");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,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(${Q.operation}, element=${Q.elementId??"MISS"});其余输出继续处理。
294
+ ${w({...Q,code:J})}`);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,z)=>{if(!Y.value)Y.value={code:X,failure:z}};$.rotating=(async()=>{try{B(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${e9(Z)}`);let X=u7({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),z,H=await n(this.chatId,X,(L)=>{z=L});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,`⚠️ 续卡发送失败,后续内容到达时会再次尝试。
295
+ ${w(z)}`);return}let G;try{G=await l$(H)}catch(L){if(B(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${L}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await I(this.chatId,`⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。
296
+ ${w(L)}`);return}E$(G,2,(L,F)=>{if($.rotating){V(L,F);return}this.onCardWriteFailure($,G,L,F)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=G,$.cardRotationFailed=!1,$.messageId=H,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,j=$.currentAssistantText??"",_=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,K&&j){let L=C.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=L,$.currentAssistantText=j,$.segmentTexts.set(L,j)}if(j)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)T0($.cardId,v2(this.taskBoard),{type:"insert_before",targetElementId:C.footer});if($.planLiveInserted)T0($.cardId,K3($.planSteps,$.planExplanation,C.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?C.taskBoardLive:C.footer});for(let L of $.contextCompactionPending.values()){if(L.cardId!==Z)continue;L.cardId=G,L.created=!1,L.createFailure=void 0;let F=C.contextCompact(L.i);L.createPromise=f4(G,W3(L.i,L.notice,F),{type:"insert_before",targetElementId:w0($)}).then((U)=>{if(L.cardId===G)L.created=U.landed,L.createFailure=U.failure;return U.landed})}for(let[L,F]of _){if(K&&j&&L===K)continue;if(!y4(Z,L))continue;let U=$.assistantSegmentCount++,A=C.assistant(U);$.segmentTexts.set(A,F),await this.addCompletedAssistantSegment($,A,F)}DY(this,Z,G,J,Q,$),await v1(Z),DY(this,Z,G,J,Q,$);let D=new Set([C.taskBoardLive,C.planLive,...[...$.contextCompactionPending.values()].map((L)=>C.contextCompact(L.i))]);if(K)D.add(K);for(let L of J.values())if(L.output==null)D.add(C.tool(L.i));if(DG(Z).some((L)=>!D.has(L)))$.cardCapacityFailures.clear();await v1(G);try{await qY($,Z);let L=$.mathRenderInflight?.get(Z);if(L?.size)await Promise.allSettled([...L]);await v1(Z);let F=$.mathRendered?.get(Z);for(let[k,E]of _){if(K&&j&&k===K)continue;if(y4(Z,k))continue;if(F?.has(k))continue;await F0(Z,k,this.completedAssistantElement(k,E))}let U=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",A=[],M=(k)=>{A.push(k)},O=await B0(Z,C.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${U}`)),{notifyCardFailure:!1,onFailure:M});a0(Z);let T=await k0(Z,b2({suffix:"\uD83D\uDCE8 转下一张"}),M);if(O&&T)await q$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${O} settings=${T}`),await I(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${O?"ok":"MISS"}, settings=${T?"ok":"MISS"}),本轮输出已续到新卡。
297
+ ${e4(A)}`)}catch(L){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${L}`)}B(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${G.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=C.planUpdate($.planUpdateCount++);T0(Z,WQ($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:w0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=C.goalUpdate(Z.goalUpdateCount++);T0(Z.cardId,KQ($,J),{type:"insert_before",targetElementId:w0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=C.goalUpdate($.goalUpdateCount++);T0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
298
+
299
+ 已清除`},{type:"insert_before",targetElementId:w0($)})}handleContextCompacted($){let Z=jj($);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<v6){B(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((U)=>U.startsWith("turn:")),V=Q??Y,X=V?this.contextCompactionReceipts.get(V):void 0;if(Q&&!X&&$.phase!=="start"&&Y){let U=this.contextCompactionReceipts.get(Y);if(!U?.hasItemAlias&&U?.completed&&Date.now()-U.completedAt<v6||!U?.hasItemAlias&&U?.completionKey&&J?.contextCompactionCompleting.has(U.completionKey))V=Y,X=U,U.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,U)}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 z=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==z){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<v6){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let U=_R($);if(J.contextCompactionPending.has(U)||J.contextCompactionCompleted.has(U)){B(`session "${this.sessionName}": duplicate context compaction start ignored key=${U}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,z,!1);let A=J.contextCompactCount++,M=J.cardId,O=C.contextCompact(A),T={i:A,cardId:M,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};T.createPromise=f4(M,W3(A,$,O),{type:"insert_before",targetElementId:w0(J)}).then((k)=>{if(T.cardId===M)T.created=k.landed,T.createFailure=k.failure;return k.landed}),J.contextCompactionPending.set(U,T),B(`session "${this.sessionName}": context compaction start #${A+1} key=${U}`),h4(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<v6){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let H=$.itemId||$.turnId;if(H&&J.contextCompactionCompleted.has(H)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${H}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:LR(J),W=G?J.contextCompactionPending.get(G):void 0,K=G??H??"__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 j=PR(W?.notice,$),_=J.contextCompactionEndOnly.get(K),D=W?.i??_??J.contextCompactCount++;if(!W&&_===void 0)J.contextCompactionEndOnly.set(K,D);J.contextCompactionCompleting.add(K);let P=[...new Set([...jj(W?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,z,!1,K);let L=C.contextCompact(D),F=W3(D,j,L);B(`session "${this.sessionName}": context compaction completion write #${D+1} key=${K}`),(async()=>{let U=!1;if(!W)while(!0){let A=J.cardId;if(U=await N2(A,F,{type:"insert_before",targetElementId:w0(J)}),U)break;let M=J.rotating;if(M){await M;continue}if(J.cardId!==A)continue;break}else while(!0){let A=W.cardId;if(await W.createPromise,W.cardId!==A)continue;if(W.created)U=await B0(A,L,F);else{if(wJ(W.createFailure?.code,W.createFailure))FG(A,L),U=await B0(A,L,F,{notifyCardFailure:!1});if(!U)U=await N2(A,F,{type:"insert_before",targetElementId:w0(J)})}if(W.cardId!==A)continue;if(U){W.created=!0;break}let M=J.rotating;if(M){await M;continue}if(W.cardId!==A)continue;break}if(J.contextCompactionCompleting.delete(K),!U){B(`session "${this.sessionName}": context compaction completion write MISS #${D+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__",P.length>0){let A=[...this.contextCompactionReceipts.entries()].filter(([,M])=>M.completionKey===K).map(([M])=>M);this.rememberContextCompactionReceipt([...new Set([...P,...A])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${D+1} key=${K}`)})().catch((U)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${x(U)}`)}),h4(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>UR){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,z]of this.contextCompactionReceipts)if(z===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?C.taskBoardLive:C.footer;Z.planLiveInserted=!0,T0(Z.cardId,K3(Z.planSteps,Z.planExplanation,C.planLive),{type:"insert_before",targetElementId:J})}else B0(Z.cardId,C.planLive,K3(Z.planSteps,Z.planExplanation,C.planLive),{notifyCardFailure:!1});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&&l7(Z)===l7(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=C.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);h4(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
300
+
301
+ `).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 (${$})`),b(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
302
+
303
+ ${J}`)}completedAssistantElement($,Z){if(GY(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 wK(Q);if(!await B0(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=w0($),V=(async()=>{if(!await N2(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(GY(J)){let z=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((H)=>B(`session "${this.sessionName}": math render ${Z} failed: ${H}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(z),z.finally(()=>$.mathRenderInflight?.get(Q)?.delete(z))}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 原始回复:
304
+
305
+ ${J}`;if(!await b(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 LK($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return Q0($)}sendOutboundPath($,Z){let J=q6($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!jR(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),u9(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: ${x(Y)}`),b(this.chatId,`❌ 文件交付失败:${x(Y)}`)}}createFileDeliveryForTurn($){return fB({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($.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Q=()=>{if($.footerStatusLabel!==Z)return;let V=$.cardId;if($.footerStatusWriteCardId===V){$.footerStatusPendingRender=Q;return}$.footerStatusPendingRender=void 0;let{label:X}=p4(Date.now()-$.footerStatusStartedAt,y6()),z=Z===_j?this.proc?.lastThinkingTokens:null,H=typeof z==="number"?` · 约 ${z} tokens`:"";$.footerStatusWriteCardId=V,this.replaceFooterContent(V,this.withModel(`${Z}${H} (${X})`)).then((G)=>{if($.footerStatusWriteCardId===V)$.footerStatusWriteCardId=void 0;if($.cardId!==V||$.footerStatusLabel===null)return;if(G.landed){let K=$.footerStatusPendingRender;$.footerStatusPendingRender=void 0,K?.();return}if($.footerStatusFailedCardId=V,$.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null;let W=$.footerStatusPendingRender;if($.footerStatusPendingRender=void 0,$.footerStatusLabel!==Z)W?.()})},Y=()=>{if($.footerStatusLabel!==Z||$.footerStatusFailedCardId===$.cardId)return;let{nextDelayMs:V}=p4(Date.now()-$.footerStatusStartedAt,y6());$.footerStatusHandle=setTimeout(()=>{Q(),Y()},Math.max(1,Math.ceil(V)))};Q(),Y()}startThinkingFooter($){this.startFooterStatus($,_j)}startWritingFooter($){this.startFooterStatus($,qR)}startWorkingFooter($){this.startFooterStatus($,DR)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null,$.footerStatusPendingRender=void 0}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 z=X.windows.find((G)=>G.kind==="fiveHour");if(Q.kind==="claude-subscription"){let G=cH(X,V),W={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(z??W,G??W)}let H=X.windows.find((G)=>G.kind==="weekly");if(z||H)return this.fmtDualWindowSuffix(z??null,H??null)}return` | ${SQ(X)}`}if($==="codex"){let X=Y??(Z?.provider==="codex"?o5(j$(Z)):null);if(!X)return" | 额度 MISS";let z=X.read();if(!z)return" | 额度 MISS";let H=W1(z.credits);return this.fmtDualWindowSuffix(z.fiveHour,z.weekly)+(H?` · ${H}`:"")}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()?u$(V.resetsAt):"",z=`${Math.round(V.percent)}%`;return X?`${X}·${z}`:z},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(x).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)g0(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"?G0(Q.tokenSourceId??this.selectedTokenSourceId,j$(Q)):this.currentTokenSource(),codexUsage:Q?.provider==="codex"&&!C0(Q.tokenSourceId)?.codexApiProvider?o5(j$(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 qY(Q),Q.fileDelivery)try{for(let O of await Q.fileDelivery.finish())Q.outboundSentPaths.add(O)}catch(O){B(`session "${this.sessionName}": file delivery close failed: ${x(O)}`),await I(this.chatId,`❌ 文件交付收尾失败:${x(O)}`)}finally{this.fileDeliveries.delete(Q.fileDelivery)}this.stopFooterStatus(Q);let Y=(Date.now()-Q.startedAt)/1000,V=Q.cardId,X=Q.segmentTexts;await v1(V);let z=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:O,currentAssistantText:T}=Q;if(!await this.addCompletedAssistantSegment(Q,O,T))z.set(O,T);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let H=Q.assistantWriteInflight?.get(V);if(H?.size)await Promise.allSettled([...H]);let G=Q.mathRenderInflight?.get(V);if(G?.size)await Promise.allSettled([...G]);let W=Q.mathRendered?.get(V);for(let[O,T]of X){if(y4(V,O)){z.set(O,T);continue}if(W?.has(O))continue;await F0(V,O,this.completedAssistantElement(O,T))}if(Q.cardRotationFailed)for(let[O,T]of X)z.set(O,T);let K=Z?Z:"✅",j=[`${K} ⏱ ${E0(Y)}`];if(J.hasFreshResult){let{contextTokens:O,contextLimit:T}=$,k=Q.provider==="claude",E=HQ(O,T,k?0:void 0);if(E)j.push(`\uD83E\uDDE0 ${E}`);let f=$.lastTurnDelta?.costUsd??0;if(f>0)j.push(`\uD83D\uDCB0 $${f.toFixed(3)}`)}if(Q.contextCompactCount>0)j.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)j.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let _=this.modelLine(Q);if(_)j.push(_);let D=j.join(" | "),P=J.hasFreshResult?GQ($.lastTurnUsage)+(Q.cardRotationFailed?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Q.model)):"",L=P?`${D}
306
+ ${P}`:D,F=[],U=(O)=>{F.push(O)},A=await B0(V,C.footer,this.footerElement(L),{onFailure:U});a0(V);let M=await k0(V,b2({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}),U);if(A&&M)await q$(V);else{let O=`footer=${A?"ok":"MISS"}, settings=${M?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${O}`),await I(this.chatId,`⚠️ 对话卡片终态写入失败 (${O})。本轮已结束: ${K}
307
+ ${e4(F)}`)}for(let O of z.values())await this.sendAssistantTextFallback(O,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.cardRotationFailed)q2(Q.messageId,[Q.userOpenId])}}});function O$($){return{card:{type:"raw",data:$}}}import{randomUUID as OR}from"node:crypto";function cY($){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:v.get(j$($.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:d0().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 qj($,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[z,H]of Object.entries(V.value)){if(!NR.has(z))throw Error(`unsupported model action field: ${z}`);if(z==="page"){if(typeof H!=="number"||!Number.isSafeInteger(H)||H<0)throw Error("invalid page");X.page=H}else{if(typeof H!=="string"||!H.trim()||H.length>1024)throw Error(`invalid ${z}`);X[z]=H.trim()}}if(!AR.has(String(X.kind)))throw Error("only model panel actions are supported");for(let z of["panel_id","source_id"])if(!X[z])throw Error(`${z} 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&&!g$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${OR()}`,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 AR,NR;var Dj=R(()=>{_0();z0();j0();AR=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"]),NR=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as RR}from"node:http";import{randomUUID as TR}from"node:crypto";function Mj($){if($.allowReply&&$.buttons?.length)throw Error(Uj);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 H of $.images??[])if(H.key)X.push({tag:"img",img_key:H.key,alt:{tag:"plain_text",content:"screenshot"}});else{let G=H.error?`
308
+ ${Q0(H.error)}`:"";X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${H.src}${G}</font>`})}if(X.push({tag:"markdown",content:CZ($.text??"")||"_(空消息)_"}),$.resolution){let H=$.resolution,G=H.kind==="text"?"已回复":`已选择:${H.text}`,W;if(H.status==="processing")W=`<font color='blue'>⏳ ${G} · 推送中…</font>`;else if(H.status==="failed")W=`<font color='red'>⚠️ ${H.kind==="text"?G:`已选:${H.text}`} · 回调失败:${Q0(H.detail??"未知")} · ${V}</font>`;else if(H.status==="delivered")W=`<font color='green'>✅ ${G} · 反馈已送达 · ${V}</font>`;else if(H.status==="unknown")W=`<font color='red'>⚠️ ${G} · 送达状态未知,禁止自动重试 · ${V}</font>`;else W=`<font color='green'>✅ ${G} · ${V}</font>`;if(X.push({tag:"markdown",content:W}),H.status==="delivered"&&H.reply)X.push({tag:"markdown",content:Q0(H.reply)})}let z=Q&&(!$.resolution||$.resolution.status==="failed");if(z&&$.buttons?.length)X.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((H)=>({tag:"button",text:{tag:"plain_text",content:H.text},type:H.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:H.id}}]}))}]});if(X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${V}</font>`}),z&&$.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 l1($,Z,J){let Q=J?.status??Z.status,Y={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${Q0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:Q0(Z.response.text)});if(Q==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
309
+ 你的下一条文字优先用于这条通知,完成后再回答 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'>${Q0(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:Q0(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 CR($){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(!SR.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>Fj)return{error:`button "${Y}" text > ${Fj} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let X=String(Q.type??"default").toLowerCase(),z=xR.has(X)?X:"default";J.push({id:Y,text:V,type:z})}return{buttons:J}}function bR($){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 Oj($){try{let Z=RR((J,Q)=>{Promise.resolve().then(async()=>{let V;try{V=new URL(J.url??"/","http://localhost")}catch{Q.statusCode=400,Q.end("bad request URL");return}if(!await $.extraHandler?.(J,Q,V))await kR(J,Q)}).catch((V)=>{if(B(`notify: handler crash: ${V?.message??V}`),!Q.headersSent)Q.statusCode=500,Q.setHeader("content-type","text/plain; charset=utf-8"),Q.end(V instanceof y0?w(V):"internal error");else try{Q.end()}catch{}})});return 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`)}),Z}catch(Z){B(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function kR($,Z,J=Z0){let Q=new URL($.url??"/","http://localhost"),Y=(c,N)=>{Z.statusCode=c,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(N)},V=(c,N)=>{Z.statusCode=c,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(N))};if($.method==="GET"&&Q.pathname==="/")return Y(200,`lodestar notify
309
310
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
310
311
  `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
311
312
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
312
313
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
313
314
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
314
315
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
315
- `);if($.method==="GET"&&Q.pathname.startsWith("/notify/result/")){let E;try{E=decodeURIComponent(Q.pathname.slice(15)).trim()}catch{return Y(400,"invalid notify_id encoding")}if(!E)return Y(400,"missing notify_id in path");let x=j1(E);if(!x)return V(404,{error:"unknown notify_id",notify_id:E});return V(200,fK(x))}if($.method!=="POST"||Q.pathname!=="/notify")return Y(405,"use POST /notify");let X="",z=0;$.setEncoding("utf8");for await(let E of $)if(z+=Buffer.byteLength(E),z<=cY)X+=E;else X="";if(z>cY)return Y(413,`request body exceeds ${cY} bytes`);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 G=H.allow_reply===!0,W=String(H.project??"").trim(),K=String(H.text??""),j=String(H.title??"").trim(),_=String(H.level??"info").toLowerCase();if(!W)return Y(400,'missing "project"');if(!K)return Y(400,'missing "text"');let{buttons:D,error:L}=LR(H.buttons);if(L)return Y(400,L);let{url:P,error:F}=qR(H.callback);if(F)return Y(400,F);let U=!!(D&&D.length);if(U&&G)return Y(400,jj);let A=U||G,M=P??"",O=jR.has(_)?_:"info",R=j||W,w=J.sanitizeSessionName(W),T=J.chatIdForSession(w);if(!T)return B(`notify: project "${W}" (sanitized "${w}") 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 f=Array.isArray(H.images)?H.images:[],u=[];for(let E of f){let x=String(E??"").trim();if(!x)continue;let p,n=await J.uploadImageKey(x,(z0)=>{p=z0});u.push({key:n??"",src:x,...p===void 0?{}:{error:v(p)}})}let C=A?`nf_${BR()}`:"",g=_j({title:R,text:K,level:O,images:u,buttons:D,allowReply:G,notifyId:C}),Y0,e=await J.sendCard(T,g,(E)=>{Y0=E});if(!e)return B(`notify: sendCard failed → 502 (project="${W}" chat=${T.slice(0,8)}…)`),Y(502,`feishu sendCard failed: ${v(Y0)}`);if(A&&C){let E={notifyId:C,callbackUrl:M,chatId:T,messageId:e,project:W,title:R,text:K,level:O,imageKeys:u,buttons:D,allowReply:G,createdAt:Date.now()};kK(E)}B(`notify: → ${W} (${T.slice(0,8)}…) level=${O} bytes=${K.length} images=${u.length} buttons=${D?.length??0} allowReply=${G} push=${A&&!!M?1:0} msg=${e}`),V(200,{ok:!0,chat_id:T,message_id:e,...C?{notify_id:C}:{}})}function u1($,Z){return _j({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var jR,_R,PR,Bj=64,jj='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply',cY=4194304;var y6=N(()=>{h();$0();o2();h0();w3();jR=new Set(["info","warn","error"]),_R=new Set(["default","primary","danger"]),PR=/^[A-Za-z0-9_-]{1,64}$/});var Dj=zV((zg,qj)=>{var{readFileSync:FR,rmSync:UR}=l2("node:fs"),{homedir:Lj}=l2("node:os"),{join:I3}=l2("node:path"),{managedClaudePluginDir:MR}=a6();function OR($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Q=Z??[I3(Lj(),".codex","skills"),I3(Lj(),".claude","skills"),I3(MR(),"skills")],Y=[];for(let V of Q){let X=I3(V,$),z=I3(X,"SKILL.md"),H;try{H=FR(z,"utf8")}catch(K){if(K.code==="ENOENT")continue;let j=Error(`skill: obsolete removal failed (${z}): ${K}`,{cause:K});J(j.message),Y.push(j);continue}let G=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(H)?.[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 ${z}`);continue}try{UR(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let j=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(j.message),Y.push(j)}}if(Y.length)throw AggregateError(Y,`Failed to remove obsolete Skill ${$}`)}qj.exports={removeManagedSkill:OR}});import{existsSync as Uj,readFileSync as Mj}from"node:fs";import{homedir as Fj}from"node:os";import{join as g3}from"node:path";function f6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[g3(Fj(),".codex","skills"),g3(Fj(),".claude","skills")];for(let Q of J){let Y=g3(Q,$.name,"SKILL.md");try{let V=Uj(Y)?Mj(Y,"utf8"):null;if(V===$.body)continue;r0(Y,$.body),B(`skill: ${V===null?"installed":"updated"} ${Y}`)}catch(V){B(`skill: sync failed (${Y}): ${V}`)}}if(!Z)AR($,d2)}function AR($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=g3(Z,".claude-plugin","plugin.json"),Q=g3(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)+`
316
- `;for(let[V,X]of[[J,Y],[Q,$.body]])try{let z=Uj(V)?Mj(V,"utf8"):null;if(z===X)continue;r0(V,X),B(`skill: ${z===null?"installed":"updated"} ${V}`)}catch(z){B(`skill: Claude plugin sync failed (${V}): ${z}`)}}function h6($,Z){Oj.removeManagedSkill($,Z,B)}var Oj;var I6=N(()=>{h();x0();H0();Oj=XV(Dj(),1)});function NR($){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`---
317
- name: ${Aj}
316
+ `);if($.method==="GET"&&Q.pathname.startsWith("/notify/result/")){let c;try{c=decodeURIComponent(Q.pathname.slice(15)).trim()}catch{return Y(400,"invalid notify_id encoding")}if(!c)return Y(400,"missing notify_id in path");let N=j1(c);if(!N)return V(404,{error:"unknown notify_id",notify_id:c});return V(200,lK(N))}if($.method!=="POST"||Q.pathname!=="/notify")return Y(405,"use POST /notify");let X="",z=0;$.setEncoding("utf8");for await(let c of $)if(z+=Buffer.byteLength(c),z<=lY)X+=c;else X="";if(z>lY)return Y(413,`request body exceeds ${lY} bytes`);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 G=H.allow_reply===!0,W=String(H.project??"").trim(),K=String(H.text??""),j=String(H.title??"").trim(),_=String(H.level??"info").toLowerCase();if(!W)return Y(400,'missing "project"');if(!K)return Y(400,'missing "text"');let{buttons:D,error:P}=CR(H.buttons);if(P)return Y(400,P);let{url:L,error:F}=bR(H.callback);if(F)return Y(400,F);let U=!!(D&&D.length);if(U&&G)return Y(400,Uj);let A=U||G,M=L??"",O=ER.has(_)?_:"info",T=j||W,k=J.sanitizeSessionName(W),E=J.chatIdForSession(k);if(!E)return B(`notify: project "${W}" (sanitized "${k}") 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 f=Array.isArray(H.images)?H.images:[],d=[];for(let c of f){let N=String(c??"").trim();if(!N)continue;let y,p=await J.uploadImageKey(N,(J0)=>{y=J0});d.push({key:p??"",src:N,...y===void 0?{}:{error:w(y)}})}let S=A?`nf_${TR()}`:"",g=Mj({title:T,text:K,level:O,images:d,buttons:D,allowReply:G,notifyId:S}),V0,e=await J.sendCard(E,g,(c)=>{V0=c});if(!e)return B(`notify: sendCard failed → 502 (project="${W}" chat=${E.slice(0,8)}…)`),Y(502,`feishu sendCard failed: ${w(V0)}`);if(A&&S){let c={notifyId:S,callbackUrl:M,chatId:E,messageId:e,project:W,title:T,text:K,level:O,imageKeys:d,buttons:D,allowReply:G,createdAt:Date.now()};gK(c)}B(`notify: → ${W} (${E.slice(0,8)}…) level=${O} bytes=${K.length} images=${d.length} buttons=${D?.length??0} allowReply=${G} push=${A&&!!M?1:0} msg=${e}`),V(200,{ok:!0,chat_id:E,message_id:e,...S?{notify_id:S}:{}})}function u1($,Z){return Mj({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var ER,xR,SR,Fj=64,Uj='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply',lY=4194304;var f6=R(()=>{h();$0();o2();h0();v3();ER=new Set(["info","warn","error"]),xR=new Set(["default","primary","danger"]),SR=/^[A-Za-z0-9_-]{1,64}$/});var Rj=GV((xg,Nj)=>{var{readFileSync:wR,rmSync:vR}=l2("node:fs"),{homedir:Aj}=l2("node:os"),{join:g3}=l2("node:path"),{managedClaudePluginDir:yR}=o6();function fR($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Q=Z??[g3(Aj(),".codex","skills"),g3(Aj(),".claude","skills"),g3(yR(),"skills")],Y=[];for(let V of Q){let X=g3(V,$),z=g3(X,"SKILL.md"),H;try{H=wR(z,"utf8")}catch(K){if(K.code==="ENOENT")continue;let j=Error(`skill: obsolete removal failed (${z}): ${K}`,{cause:K});J(j.message),Y.push(j);continue}let G=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(H)?.[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 ${z}`);continue}try{vR(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let j=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(j.message),Y.push(j)}}if(Y.length)throw AggregateError(Y,`Failed to remove obsolete Skill ${$}`)}Nj.exports={removeManagedSkill:fR}});import{existsSync as Ej,readFileSync as xj}from"node:fs";import{homedir as Tj}from"node:os";import{join as m3}from"node:path";function h6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[m3(Tj(),".codex","skills"),m3(Tj(),".claude","skills")];for(let Q of J){let Y=m3(Q,$.name,"SKILL.md");try{let V=Ej(Y)?xj(Y,"utf8"):null;if(V===$.body)continue;r0(Y,$.body),B(`skill: ${V===null?"installed":"updated"} ${Y}`)}catch(V){B(`skill: sync failed (${Y}): ${V}`)}}if(!Z)hR($,d2)}function hR($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=m3(Z,".claude-plugin","plugin.json"),Q=m3(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)+`
317
+ `;for(let[V,X]of[[J,Y],[Q,$.body]])try{let z=Ej(V)?xj(V,"utf8"):null;if(z===X)continue;r0(V,X),B(`skill: ${z===null?"installed":"updated"} ${V}`)}catch(z){B(`skill: Claude plugin sync failed (${V}): ${z}`)}}function I6($,Z){Sj.removeManagedSkill($,Z,B)}var Sj;var g6=R(()=>{h();x0();H0();Sj=HV(Rj(),1)});function IR($){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`---
318
+ name: ${Cj}
318
319
  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.")}
319
320
  ---
320
321
 
@@ -573,20 +574,20 @@ is the script's acknowledgement, distinct from the user's response.
573
574
  Hand-edits will be overwritten — set
574
575
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
575
576
  to maintain the file yourself.
576
- `}function Nj(){f6({name:Aj,body:NR(m.notify.port)})}var Aj="feishu-notify";var Rj=N(()=>{f0();I6()});import{randomUUID as RR}from"node:crypto";function Tj($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,z)=>{if(!V)return"通知已过期或已移除";if(!z)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(i4(V.notifyId))return"通知正在处理中";return null},Q=async(V,X)=>{$.log(`notify-reply: ${X}`);let z;if(!await $.sendText(V,`❌ ${X}`,(H)=>{z=H}))throw Error(`通知回复错误提示发送失败: ${v(z)};原错误:${X}`)},Y=async(V,X,z,H)=>{try{await $.updateCard(X,z)}catch(G){await Q(V.chatId,`${H},卡片更新失败:${v(G)}`)}};return{async recover(V){if(V.dispatchState&&V.unknownAt){let H=V.dispatchState,G=V.buttons.find((W)=>W.id===H.buttonId);await Y(V,V.messageId,u1(V,{status:"unknown",buttonId:H.buttonId,text:G?.text??H.buttonId,operatorOpenId:H.openId,detail:V.unknownReason}),"按钮回调送达状态未知");return}let X=V.replyState;if(!X||!V.unknownAt)return;let z={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Y(V,X.promptMessageId,l1(V,X,z),"回复送达状态未知"),await Y(V,V.messageId,u1(V,z),"回复送达状态未知")},async open(V,X,z){let H=j1(V),G=J(H,X,z);if(G||!H)return{ok:!1,message:G};if(H.replyState?.status==="waiting"||H.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let W=WY(H.chatId);if(W.some((K)=>K.replyState?.status==="sending"||i4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};S3(V);try{for(let D of W){let L={...D.replyState,status:"cancelled",cancelReason:"switched"};n4(D.notifyId,L),await Y(D,L.promptMessageId,l1(D,L),"已放弃上一条回复并切换通知")}let K={id:RR(),openId:z,promptMessageId:"",openedAt:Date.now(),status:"waiting"},j,_=await $.sendCard(H.chatId,l1(H,K),(D)=>{j=D});if(!_)return{ok:!1,message:`等待输入卡片发送失败,未开始接收回复,请重新点击「回复」
577
- ${v(j)}`};K.promptMessageId=_;try{n4(V,K)}catch(D){let L=`等待输入状态保存失败,未开始接收回复:${Z(D)}`;return await Y(H,_,l1(H,K,{status:"failed",detail:L}),L),{ok:!1,message:L,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{C3(V),$.onWaitingChanged(H.chatId)}},async cancel(V,X,z,H){let G=j1(V),W=J(G,z,H);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!==H)return{ok:!1,message:"仅点击「回复」的人可以取消"};let j={...K,status:"cancelled"};return n4(V,j),$.onWaitingChanged(G.chatId),await Y(G,K.promptMessageId,l1(G,j),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:z,messageId:H,text:G,createTime:W}=V;if(!z||!H||!G.trim())return!1;if(yK(X,H))return!0;let K=b3(X,z);if(!K?.replyState)return!1;let j=K.replyState;if(W>0&&W<j.openedAt)return!1;if(j.status!=="waiting"||i4(K.notifyId))return await Q(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let _={text:G,message_id:H,prompt_message_id:j.promptMessageId},D={...j,status:"sending",response:_};S3(K.notifyId);try{try{n4(K.notifyId,D)}catch(U){return await Q(X,`回复保存失败,尚未回传,请重新输入:${Z(U)}`),!0}let L;try{try{await $.updateCard(j.promptMessageId,l1(K,D))}catch(U){throw Error(v(U))}if(K.callbackUrl)L=await $.dispatch(K,_,z);else k3(K.notifyId,void 0,z),L={ok:!0,detail:"已记录"}}catch(U){L={ok:!1,detail:Z(U)}}let P;if(L.ok){let U=K.callbackUrl?D6(K.notifyId,void 0,z):{state:"complete"};P={kind:"text",text:G,operatorOpenId:z,status:U.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...U.state==="unknown"?{detail:U.detail}:{reply:L.reply}}}else{P={kind:"text",text:G,operatorOpenId:z,status:"failed",detail:L.detail};try{n4(K.notifyId,{...D,status:"failed",error:L.detail})}catch(U){let A=`${L.detail};失败状态保存失败:${Z(U)}`;try{q6(K.notifyId,void 0,z,A)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}P={...P,status:"unknown",detail:A}}}let F=P.status==="delivered"?"回复已送达":P.status==="done"?"回复已记录":P.status==="unknown"?`回复送达状态未知:${P.detail}`:`回复未送达:${P.detail}`;return await Y(K,j.promptMessageId,l1(K,D,P),F),await Y(K,K.messageId,u1(K,P),F),$.log(`notify-reply: notify_id=${K.notifyId} status=${P.status}`),!0}finally{C3(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var Ej=N(()=>{w3();y6()});function xj($){let Z=lY($,"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((G)=>G.trim()).filter(Boolean))],Y=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=$9(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=wj(Z.prompt,'agent run requires "prompt"'),z=$9(Z.effort),H=bj(Z);return{identityIds:Q,description:Z9(Z.description),prompt:X,...z?{effort:z}:{},...V?{sessionId:V}:{},...H!==void 0?{workDir:H}:{},...Cj(Z)}}function Sj($){let Z=lY($,"agent follow-up request"),J=wj(Z.prompt,'agent follow-up requires "prompt"'),Q=$9(Z.identity_id??Z.identityId),Y=$9(Z.effort),V=bj(Z);return{description:Z9(Z.description),prompt:J,...Q?{identityId:Q}:{},...Y?{effort:Y}:{},...V!==void 0?{workDir:V}:{},...Cj(Z)}}function Cj($){let Z={};for(let[J,Q]of[["request_id","requestId"],["requester_open_id","requesterOpenId"]]){if($[J]===void 0)continue;let Y=$[J];if(typeof Y!=="string"||!Y.trim()||Y.length>200||/[\x00-\x1f]/.test(Y))throw Error(`invalid ${J}`);Z[Q]=Y.trim()}return Z}function o0($){return $.owner??{kind:"session",name:$.sessionName,chatId:$.chatId,workDir:$.sessionWorkDir??$.workDir}}function q1($){return JSON.stringify([$.kind,$.name,$.chatId,$.workDir])}function g6($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function bj($){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:g6(Z)}function Z9($){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 kj($){let Z=lY($,"agent answer request"),J=$9(Z.identity_id??Z.identityId),Q=$9(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 lY($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function wj($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function $9($){return(typeof $==="string"?$.trim():"")||void 0}function TR(){return["---",`name: ${vj}`,`description: ${JSON.stringify("Lodestar Agent calls: main Agents must bind calls to their managed session; independent services and applications must bind calls to a project. Resume unique native session IDs only within the same project and group. Delegated Agents and subagents must not 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.","","## 调用归属(强制)","","| 调用场景 | 必须使用的绑定 |","| --- | --- |","| Agent 正在执行用户任务,需要调用另一个 Agent / 模型辅助执行 | 绑定当前会话:使用普通 `lodestar-agent` 命令,不传 `--project` |","| 独立服务、定时任务或其他软件直接调用 | 绑定项目:每个命令都显式传 `--project <项目名>` |","","- Agent 通过 Shell、Python、脚本或 HTTP 发起的调用仍然属于 Agent 执行任务,必须绑定会话。","- 不得把当前任务中的调用包装成“外部服务”,不得清除会话环境变量、复制项目凭据或使用 `--project` 脱离会话生命周期。","- 没有有效会话上下文时,Agent 调用必须报错;项目入口不是会话凭据缺失、过期或失败时的替代路径。","- 独立服务和软件不借用任何主 Agent 的会话凭据,统一使用项目入口。项目任务有自己的卡片和取消入口,不依赖主会话存活。","","## 会话 ID 与恢复范围(强制)","","- `session_id`(JSON 的 `workers[].session_id`)是原生会话的唯一 ID,续跑保持不变。","- `run_id` 只标识某一次调用记录,不是另一个会话 ID;不要为绑定方式或续跑创建第二套会话标识。","- 会话始终归属项目和群。同一项目、同一群内的会话 ID 可以互相恢复,包括会话绑定和项目绑定产生的会话。","- 禁止跨项目或跨群恢复。项目按登记的规范工作目录识别,执行子目录不改变项目归属;群必须是同一个 chat_id。","- 无法确认项目和群归属的 ID 必须报错,不能因传入 `--project`、`--identity` 或某个目录就认定它属于当前项目。","- `--workdir` 可以调整到本项目内的现有目录;`--identity` 可以选择原后端下的其他模型或来源。原生会话不能更换所属后端。","- 恢复本轮的绑定由调用场景决定,旧调用记录不迁移;切换绑定方式不建立相互取消关系。","- 同一个原生会话不能同时执行两轮,恢复失败必须显示,不得自动新建会话。","","## 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.","- The Agent workflow below always uses session-bound calls. `--project` is reserved"," for genuinely independent service/application clients, not Agent task execution.","","## 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` may select an existing directory within the same project.","Without `--workdir`, reuse the recorded execution directory. A different project","directory or unknown session ownership is an error. 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. Recorded identity and effort","are reused when omitted. Explicit `--identity` may select another model/source in the same backend;","a changed identity uses its default effort unless `--effort` is given. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","Only ids registered to the current project and group can be resumed. The original","invocation may have been session-bound or project-bound; unknown ownership is rejected.","The new run belongs to the current caller; previous ownership is not transferred.","Changing binding mode within the project does not join cancellation trees. Backend resume failures","remain errors. Wait for that worker to exit; other workers in its run need not finish.","Concurrent turns on the same provider/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.","Empty ids, unknown project/group ownership, and cross-project/group ids are rejected.","The original backend then determines whether the native conversation can be resumed;","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.","- Never read or copy daemon project-client credentials to bypass delegation restrictions.","- 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.","- Both session-bound and project-bound Agents return results and local artifact paths to the caller.","- The caller owns file delivery. Agent output markers do not upload files or grant sharing permissions.",""].join(`
578
- `)}function gj(){h6("lodestar-consult"),f6({name:vj,body:TR()})}var vj="lodestar-agent",yj,fj,hj,Ij;var uY=N(()=>{I6();yj=["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."],fj=["Return task results and local artifact paths to the caller; the caller is responsible for delivering files to the user.","Do not emit file-delivery markers or upload, share, or send generated files to Feishu.","These rules replace any earlier Lodestar file-delivery instructions, including those in a resumed conversation."],hj=["You are a delegated Agent working on a task assigned by the main Agent.",...yj,"If additional Agent work is needed, report the need to the main Agent so it can assign that work.",...fj].join(`
579
- `),Ij=["You are executing a project task for the calling service or application through Lodestar.",...yj,"If additional Agent work is needed, report the need to the caller.",...fj].join(`
580
- `)});function mj($){let Z=G0($.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}=H3({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,$.projectBound?Ij:hj].filter(Boolean).join(`
577
+ `}function bj(){h6({name:Cj,body:IR(m.notify.port)})}var Cj="feishu-notify";var kj=R(()=>{f0();g6()});import{randomUUID as gR}from"node:crypto";function wj($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,z)=>{if(!V)return"通知已过期或已移除";if(!z)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(i4(V.notifyId))return"通知正在处理中";return null},Q=async(V,X)=>{$.log(`notify-reply: ${X}`);let z;if(!await $.sendText(V,`❌ ${X}`,(H)=>{z=H}))throw Error(`通知回复错误提示发送失败: ${w(z)};原错误:${X}`)},Y=async(V,X,z,H)=>{try{await $.updateCard(X,z)}catch(G){await Q(V.chatId,`${H},卡片更新失败:${w(G)}`)}};return{async recover(V){if(V.dispatchState&&V.unknownAt){let H=V.dispatchState,G=V.buttons.find((W)=>W.id===H.buttonId);await Y(V,V.messageId,u1(V,{status:"unknown",buttonId:H.buttonId,text:G?.text??H.buttonId,operatorOpenId:H.openId,detail:V.unknownReason}),"按钮回调送达状态未知");return}let X=V.replyState;if(!X||!V.unknownAt)return;let z={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Y(V,X.promptMessageId,l1(V,X,z),"回复送达状态未知"),await Y(V,V.messageId,u1(V,z),"回复送达状态未知")},async open(V,X,z){let H=j1(V),G=J(H,X,z);if(G||!H)return{ok:!1,message:G};if(H.replyState?.status==="waiting"||H.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let W=KY(H.chatId);if(W.some((K)=>K.replyState?.status==="sending"||i4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};C3(V);try{for(let D of W){let P={...D.replyState,status:"cancelled",cancelReason:"switched"};n4(D.notifyId,P),await Y(D,P.promptMessageId,l1(D,P),"已放弃上一条回复并切换通知")}let K={id:gR(),openId:z,promptMessageId:"",openedAt:Date.now(),status:"waiting"},j,_=await $.sendCard(H.chatId,l1(H,K),(D)=>{j=D});if(!_)return{ok:!1,message:`等待输入卡片发送失败,未开始接收回复,请重新点击「回复」
578
+ ${w(j)}`};K.promptMessageId=_;try{n4(V,K)}catch(D){let P=`等待输入状态保存失败,未开始接收回复:${Z(D)}`;return await Y(H,_,l1(H,K,{status:"failed",detail:P}),P),{ok:!1,message:P,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{b3(V),$.onWaitingChanged(H.chatId)}},async cancel(V,X,z,H){let G=j1(V),W=J(G,z,H);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!==H)return{ok:!1,message:"仅点击「回复」的人可以取消"};let j={...K,status:"cancelled"};return n4(V,j),$.onWaitingChanged(G.chatId),await Y(G,K.promptMessageId,l1(G,j),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:z,messageId:H,text:G,createTime:W}=V;if(!z||!H||!G.trim())return!1;if(cK(X,H))return!0;let K=k3(X,z);if(!K?.replyState)return!1;let j=K.replyState;if(W>0&&W<j.openedAt)return!1;if(j.status!=="waiting"||i4(K.notifyId))return await Q(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let _={text:G,message_id:H,prompt_message_id:j.promptMessageId},D={...j,status:"sending",response:_};C3(K.notifyId);try{try{n4(K.notifyId,D)}catch(U){return await Q(X,`回复保存失败,尚未回传,请重新输入:${Z(U)}`),!0}let P;try{try{await $.updateCard(j.promptMessageId,l1(K,D))}catch(U){throw Error(w(U))}if(K.callbackUrl)P=await $.dispatch(K,_,z);else w3(K.notifyId,void 0,z),P={ok:!0,detail:"已记录"}}catch(U){P={ok:!1,detail:Z(U)}}let L;if(P.ok){let U=K.callbackUrl?F6(K.notifyId,void 0,z):{state:"complete"};L={kind:"text",text:G,operatorOpenId:z,status:U.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...U.state==="unknown"?{detail:U.detail}:{reply:P.reply}}}else{L={kind:"text",text:G,operatorOpenId:z,status:"failed",detail:P.detail};try{n4(K.notifyId,{...D,status:"failed",error:P.detail})}catch(U){let A=`${P.detail};失败状态保存失败:${Z(U)}`;try{D6(K.notifyId,void 0,z,A)}catch(M){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(M)}`)}L={...L,status:"unknown",detail:A}}}let F=L.status==="delivered"?"回复已送达":L.status==="done"?"回复已记录":L.status==="unknown"?`回复送达状态未知:${L.detail}`:`回复未送达:${L.detail}`;return await Y(K,j.promptMessageId,l1(K,D,L),F),await Y(K,K.messageId,u1(K,L),F),$.log(`notify-reply: notify_id=${K.notifyId} status=${L.status}`),!0}finally{b3(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var vj=R(()=>{v3();f6()});function yj($){let Z=uY($,"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((G)=>G.trim()).filter(Boolean))],Y=Z.session_id!==void 0?Z.session_id:Z.sessionId,V=$9(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=mj(Z.prompt,'agent run requires "prompt"'),z=$9(Z.effort),H=Ij(Z);return{identityIds:Q,description:Z9(Z.description),prompt:X,...z?{effort:z}:{},...V?{sessionId:V}:{},...H!==void 0?{workDir:H}:{},...hj(Z)}}function fj($){let Z=uY($,"agent follow-up request"),J=mj(Z.prompt,'agent follow-up requires "prompt"'),Q=$9(Z.identity_id??Z.identityId),Y=$9(Z.effort),V=Ij(Z);return{description:Z9(Z.description),prompt:J,...Q?{identityId:Q}:{},...Y?{effort:Y}:{},...V!==void 0?{workDir:V}:{},...hj(Z)}}function hj($){let Z={};for(let[J,Q]of[["request_id","requestId"],["requester_open_id","requesterOpenId"]]){if($[J]===void 0)continue;let Y=$[J];if(typeof Y!=="string"||!Y.trim()||Y.length>200||/[\x00-\x1f]/.test(Y))throw Error(`invalid ${J}`);Z[Q]=Y.trim()}return Z}function o0($){return $.owner??{kind:"session",name:$.sessionName,chatId:$.chatId,workDir:$.sessionWorkDir??$.workDir}}function q1($){return JSON.stringify([$.kind,$.name,$.chatId,$.workDir])}function m6($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function Ij($){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:m6(Z)}function Z9($){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 gj($){let Z=uY($,"agent answer request"),J=$9(Z.identity_id??Z.identityId),Q=$9(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 uY($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function mj($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function $9($){return(typeof $==="string"?$.trim():"")||void 0}var m2="project Agent calls are non-interactive and have no question or answer interface; complete the supplied goal autonomously";function mR(){return["---",`name: ${pj}`,`description: ${JSON.stringify("Lodestar Agent calls: main Agents must bind calls to their managed session; independent services and applications must bind calls to a project. Resume unique native session IDs only within the same project and group. Delegated Agents and subagents must not 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.","","## 调用归属(强制)","","| 调用场景 | 必须使用的绑定 |","| --- | --- |","| Agent 正在执行用户任务,需要调用另一个 Agent / 模型辅助执行 | 绑定当前会话:使用普通 `lodestar-agent` 命令,不传 `--project` |","| 独立服务、定时任务或其他软件直接调用 | 绑定项目:每个命令都显式传 `--project <项目名>` |","","- Agent 通过 Shell、Python、脚本或 HTTP 发起的调用仍然属于 Agent 执行任务,必须绑定会话。","- 不得把当前任务中的调用包装成“外部服务”,不得清除会话环境变量、复制项目凭据或使用 `--project` 脱离会话生命周期。","- 没有有效会话上下文时,Agent 调用必须报错;项目入口不是会话凭据缺失、过期或失败时的替代路径。","- 独立服务和软件不借用任何主 Agent 的会话凭据,统一使用项目入口。项目任务有自己的卡片和取消入口,不依赖主会话存活。","- 项目入口不提供提问或回答接口:新建和续跑均须自主执行必要步骤并验证,直至完整完成调用方目标,不以计划、部分工作或索取输入结束;`answer` 仅供主 Agent 的会话委派使用。","","## 会话 ID 与恢复范围(强制)","","- `session_id`(JSON 的 `workers[].session_id`)是原生会话的唯一 ID,续跑保持不变。","- `run_id` 只标识某一次调用记录,不是另一个会话 ID;不要为绑定方式或续跑创建第二套会话标识。","- 会话始终归属项目和群。同一项目、同一群内的会话 ID 可以互相恢复,包括会话绑定和项目绑定产生的会话。","- 禁止跨项目或跨群恢复。项目按登记的规范工作目录识别,执行子目录不改变项目归属;群必须是同一个 chat_id。","- 无法确认项目和群归属的 ID 必须报错,不能因传入 `--project`、`--identity` 或某个目录就认定它属于当前项目。","- `--workdir` 可以调整到本项目内的现有目录;`--identity` 可以选择原后端下的其他模型或来源。原生会话不能更换所属后端。","- 恢复本轮的绑定由调用场景决定,旧调用记录不迁移;切换绑定方式不建立相互取消关系。","- 同一个原生会话不能同时执行两轮,恢复失败必须显示,不得自动新建会话。","","## 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.","- The Agent workflow below always uses session-bound calls. `--project` is reserved"," for genuinely independent service/application clients, not Agent task execution.","","## 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` may select an existing directory within the same project.","Without `--workdir`, reuse the recorded execution directory. A different project","directory or unknown session ownership is an error. 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. Recorded identity and effort","are reused when omitted. Explicit `--identity` may select another model/source in the same backend;","a changed identity uses its default effort unless `--effort` is given. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","Only ids registered to the current project and group can be resumed. The original","invocation may have been session-bound or project-bound; unknown ownership is rejected.","The new run belongs to the current caller; previous ownership is not transferred.","Changing binding mode within the project does not join cancellation trees. Backend resume failures","remain errors. Wait for that worker to exit; other workers in its run need not finish.","Concurrent turns on the same provider/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.","Empty ids, unknown project/group ownership, and cross-project/group ids are rejected.","The original backend then determines whether the native conversation can be resumed;","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","","Only session-bound delegation can return `Status: needs_input`; project-bound service calls never ask for input and do not support `answer`.","When a session-bound 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.","- Never read or copy daemon project-client credentials to bypass delegation restrictions.","- 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.","- Both session-bound and project-bound Agents return results and local artifact paths to the caller.","- The caller owns file delivery. Agent output markers do not upload files or grant sharing permissions.",""].join(`
579
+ `)}function ij(){I6("lodestar-consult"),h6({name:pj,body:mR()})}var pj="lodestar-agent",cj,lj,uj,dj;var dY=R(()=>{g6();cj=["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."],lj=["Return task results and local artifact paths to the caller; the caller is responsible for delivering files to the user.","Do not emit file-delivery markers or upload, share, or send generated files to Feishu.","These rules replace any earlier Lodestar file-delivery instructions, including those in a resumed conversation."],uj=["You are a delegated Agent working on a task assigned by the main Agent.",...cj,"If additional Agent work is needed, report the need to the main Agent so it can assign that work.","If clarification is necessary, you may use question tools to ask the main Agent. This session-bound interaction policy replaces any non-interactive project-call policy from earlier turns.",...lj].join(`
580
+ `),dj=["You are executing a project task for the calling service or application through Lodestar.","This is a non-interactive execution entry point with no question or answer interface. The caller is traditional software; nobody is available to answer questions.","Do not ask the user or caller questions, request clarification or confirmation, or wait for input. Do not use question tools or other channels to solicit a reply.","The supplied goal is your completion requirement. Execute every necessary step and verify the result; keep working until the entire goal is achieved within the authorized scope. A plan, partial work, or a request for another turn is not completion.","Resolve missing context by inspecting the available project, files, tools, and task inputs. Make routine implementation decisions yourself. Do not stop merely because you would prefer clarification or more instructions.","Only when a concrete blocker prevents further authorized progress, return an explicit failure reason with evidence of the blocker and the work already performed. Never invent missing facts or claim an incomplete goal is complete.","These non-interactive rules apply to this invocation and replace earlier instructions to ask questions, including instructions in a resumed conversation.",...cj,"Complete the required work yourself; do not return requests for the caller to arrange additional Agent work.",...lj].join(`
581
+ `)});function nj($){let Z=G0($.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}=G3({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,$.projectBound?dj:uj].filter(Boolean).join(`
581
582
 
582
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return ER(Q,$.prompt,$.callbacks,void 0,$.resumeSessionId)}function ER($,Z,J={},Q=RX,Y){let V=[],X=null,z=!1,H=null,G=null,W=[],K,j,_=Date.now(),D=new Promise((E,x)=>{K=E,j=x}),L=(E)=>{if(!E)return null;try{if(!Y||E!==Y)Q($.provider,E);if(Y&&E!==Y)throw Error(`native resume returned session ${E}, expected ${Y}; refusing to treat it as a resumed conversation`);return J.onSession?.(E),null}catch(x){return x instanceof Error?x:Error(String(x))}},P=()=>{if($.off("assistant_text",U),$.off("tool_use",M),$.off("tool_result",O),$.off("subagent_step",R),$.off("can_use_tool",w),$.off("hook_callback",T),$.off("init",f),!$.isAlive())$.off("error",u);$.off("turn_retry",g),$.off("codex_account_changed",C),$.off("result",Y0),$.off("exit",e)},F=(E,x)=>{if(H)return H;return z=!0,W.length=0,H=Promise.resolve().then(async()=>{let p=L($.sessionId);try{await $.kill(3000)}catch(n1){G=n1 instanceof Error?n1:Error(String(n1))}P();let n=[E,p,G].filter((n1)=>!!n1),z0=n.length>1?AggregateError(n,n.map((n1)=>n1.message).join("; ")):n[0];if(z0){j(new m3(z0,V.join("").trim(),$.sessionId));return}let k$=$.sessionId;if(!k$){j(new m3(Error("delegated agent completed without a native session id"),V.join("").trim(),null));return}let p2=V.join("").trim(),c2=CR(x?.checkpoint,$);K({output:p2,outputTruncated:!1,sessionId:k$,...c2?{checkpointId:c2}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),H},U=(E)=>{if(z||E?.parentToolUseId||typeof E?.text!=="string")return;V.push(E.text)},A=(E)=>{if(z)return;try{J.onProgress?.(E)}catch(x){F(x instanceof Error?x:Error(String(x)))}},M=(E)=>A({at:new Date().toISOString(),phase:"started",tool:String(E?.name??"tool"),detail:""}),O=(E)=>A({at:new Date().toISOString(),phase:"completed",tool:E?.is_error?"tool error":"tool result",detail:""}),R=(E)=>A({at:new Date().toISOString(),phase:E?.phase??"info",tool:String(E?.tool??"subagent"),detail:""}),w=(E)=>{if(z)return;if(E.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(E.request_id,"allow",{updatedInput:E.input??{}})}catch(p){F(p instanceof Error?p:Error(String(p)))}return}let x;try{x=xR(E)}catch(p){F(p instanceof Error?p:Error(String(p)));return}if(W.some((p)=>p.request.requestId===x.requestId))return;W.push({request:x,originalInput:E.input??{}});try{if(W.length===1)J.onNeedsInput?.(x)}catch(p){F(p instanceof Error?p:Error(String(p)))}},T=(E)=>{if(z)return;try{$.sendHookResponse(String(E.request_id),{})}catch(x){F(x instanceof Error?x:Error(String(x)))}},f=(E)=>{let x=L(E?.session_id??$.sessionId);if(x)F(x)},u=(E)=>{X=E instanceof Error?E:Error(String(E))},C=(E)=>{if(z)return;try{J.onCodexAccount?.(E.accountId)}catch(x){F(x instanceof Error?x:Error(String(x)))}if(E.diagnostics.length)B(`agent-runner: selected Codex account=${E.accountId}; diagnostics: ${E.diagnostics.join(";")}`)},g=(E)=>{A({at:new Date().toISOString(),phase:"info",tool:E.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:E.phase==="waiting"?`${E.message} · ${E.delayMs/1000}s 后重试 #${E.attempt}`:`正在重试 #${E.attempt}`})},Y0=(E)=>{let x=E?.is_error?Error(String(E.error??E.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;F(x,E)},e=(E)=>{if(z)return;let x=`code=${E?.code??"null"} signal=${E?.signal??"null"}`;F(X??Error(`delegated agent exited before result (${x})`))};$.on("assistant_text",U),$.on("tool_use",M),$.on("tool_result",O),$.on("subagent_step",R),$.on("can_use_tool",w),$.on("hook_callback",T),$.on("init",f),$.on("error",u),$.on("turn_retry",g),$.on("codex_account_changed",C),$.on("result",Y0),$.on("exit",e);try{$.sendInitialize(),$.sendUserText(Z)}catch(E){F(E instanceof Error?E:Error(String(E)))}return{done:D,isAlive:()=>$.isAlive(),pendingInput:()=>W[0]?.request??null,answer(E,x){let p=W[0];if(!p)throw Error("delegated agent is not waiting for input");if(p.request.requestId!==E)throw Error(`delegated agent input request mismatch: expected ${p.request.requestId}`);if($.sendPermissionResponse(E,"allow",{updatedInput:{...p.originalInput,answers:x}}),W.shift(),W[0])J.onNeedsInput?.(W[0].request)},async cancel(E="delegated agent cancelled"){let x=z;if(await F(Error(E)),await D.catch(()=>{}),x){if($.isAlive())await $.kill(3000);G=null,P()}if(G)throw G}}}function xR($){let Z=$.input??{},Q=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Y,V)=>SR(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 SR($,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 z=X&&typeof X==="object"?X:{};return{label:String(z.label??z.value??""),...z.description?{description:String(z.description)}:{}}}).filter((X)=>X.label):[];return{id:Y,...J.header?{header:String(J.header)}:{},question:Q,options:V}}function CR($,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 m3;var pj=N(()=>{ZQ();q9();X0();uY();h();m3=class m3 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});function W$($){if($.kind!=="session")return $.context;let Z=$.session;return{owner:{kind:"session",name:Z.sessionName,chatId:Z.chatId,workDir:Z.workDir},codexAccountId:Z.codexAccountId(),sessionInstructions:(J)=>Z.delegatedAgentDeveloperInstructions(J)}}import{createHash as cj,randomBytes as bR,randomUUID as kR}from"node:crypto";import{existsSync as wR,readdirSync as vR,readFileSync as rj,realpathSync as m6,statSync as yR}from"node:fs";import{isAbsolute as fR,join as p6,relative as hR,resolve as ej,sep as IR}from"node:path";class oY{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;pendingRunCreations=new Set;requests=new Map;shuttingDown=!1;constructor($=gR){this.deps=$;this.presentation=new T3($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}projectPrincipal($){if($.owner.kind!=="project")throw Error("project principal requires project ownership");return{kind:"project",context:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}startRun($,Z){return this.withRequestId($,Z,"run",(J)=>this.startRunOnce($,Z,J))}async startRunOnce($,Z,J){if(this.assertAcceptingRuns(),$.kind==="worker")throw Error(iY);if(Z9(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 Y=this.findSessionHistory($,Z.sessionId),V=Z.identityIds[0]?this.requireIdentity($,Z.identityIds[0]):void 0;return this.resumeRun($,Z,J,Y,V)}let Q=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun(W$($),Z,{...J,cancellationEpoch:this.currentCancellationEpoch(W$($))})}finally{Q()}}followUp($,Z,J){return this.withRequestId($,J,`follow-up:${Z}`,(Q)=>this.followUpOnce($,Z,J,Q))}async followUpOnce($,Z,J,Q){if(this.assertAcceptingRuns(),$.kind==="worker")throw Error(iY);Z9(J.description);let Y=this.runs.get(Z);if(!Y)throw Error(`agent run not found: ${Z}`);this.assertResumeProject($,Y);let V=Y.snapshot.workers.length===1?Y.snapshot.workers[0]:oj(Y.snapshot,J.identityId);if(Y.handles.get(V.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!V.sessionId)throw Error(`${V.identityName} has no resumable native session id`);this.findSessionHistory($,V.sessionId);let X=J.identityId?this.requireIdentity($,J.identityId):void 0;return this.resumeRun($,{...J,identityIds:J.identityId?[J.identityId]:[],sessionId:V.sessionId},Q,{run:Y,worker:V},X)}requireIdentity($,Z){let J=this.deps.getCatalog(W$($).codexAccountId).identities.find((Q)=>Q.id===Z);if(!J)throw Error(`agent identity not found: ${Z}`);if(J.status!=="ready")throw Error(`${J.displayName}: ${J.reason??J.status}`);return J}async resumeRun($,Z,J,Q,Y){let V=W$($);this.assertResumeProject($,Q.run);let X=Y??this.requireIdentity($,Q.worker.identityId);if(X.provider!==Q.worker.provider)throw Error("native session belongs to a different Agent backend");let z=q1(o0(Q.run.snapshot))===q1(V.owner),H=Z.effort??(Q.worker.identityId===X.id?Q.worker.effort:void 0),G=Z.workDir??Q.run.snapshot.workDir,W=this.reserveCapacity($,1),K;try{return K=this.reserveNativeSession({provider:X.provider,sessionId:Z.sessionId}),await this.createRun(V,{identityIds:[X.id],description:Z.description,prompt:Z.prompt,effort:H,workDir:G,requesterOpenId:Z.requesterOpenId??(z?Q.run.snapshot.requesterOpenId:void 0)},{...J,...z?{parentRunId:Q.run.snapshot.runId,parentKind:"follow_up"}:{},resumedFromRunId:Q.run.snapshot.runId,cancellationEpoch:this.currentCancellationEpoch(V),resumeSessionId:Z.sessionId})}finally{K?.(),W()}}async answer($,Z,J){let Q=this.requireMutableDescendant($,Z),Y=oj(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)=>o0(V.snapshot).kind==="session"&&V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Y=await Promise.allSettled(Q.map((V)=>this.cancelTree(V,J)));nY(Y)}async cancelProjectRunFromCard($,Z,J,Q){let Y=this.runs.get($);if(!Y||o0(Y.snapshot).kind!=="project"||!Q||!J||Y.snapshot.chatId!==Z||Y.snapshot.cardMessageId!==J)throw Error("项目任务卡片无效或不属于当前群");return this.cancelRun(this.projectPrincipal({owner:o0(Y.snapshot)}),$,"用户通过项目任务卡取消")}async withRequestId($,Z,J,Q){if($.kind==="worker")throw Error(iY);if((Z.requestId||Z.requesterOpenId)&&$.kind!=="project")throw Error("request_id and requester_open_id require explicit project mode");if(!Z.requestId)return Q({});let Y=q1(W$($).owner),V=JSON.stringify([Y,Z.requestId]),X=cj("sha256").update(JSON.stringify({operation:J,prompt:Z.prompt,description:Z.description,effort:Z.effort,workDir:Z.workDir,requesterOpenId:Z.requesterOpenId,identityIds:"identityIds"in Z?Z.identityIds:void 0,identityId:"identityId"in Z?Z.identityId:void 0,sessionId:"sessionId"in Z?Z.sessionId:void 0})).digest("hex"),z=[...this.runs.values()].find((W)=>W.snapshot.requestId===Z.requestId&&q1(o0(W.snapshot))===Y);if(z){if(z.snapshot.requestHash!==X)throw Error("request_id was already used with different input");return this.readSnapshot(z)}let H=this.requests.get(V);if(H){if(H.hash!==X)throw Error("request_id is in use with different input");return H.promise}let G=Promise.resolve().then(()=>Q({requestId:Z.requestId,requestHash:X}));this.requests.set(V,{hash:X,promise:G});try{return await G}finally{this.requests.delete(V)}}async shutdown($){this.shuttingDown=!0;let Z=new Set([...this.runs.values()].map((X)=>`${X.snapshot.sessionName}\x00${X.snapshot.chatId}`));for(let X of Z){let[z,H]=X.split("\x00");this.bumpCancellationEpoch(z,H)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Q=await Promise.allSettled([...J.map((X)=>this.cancelTree(X,$)),...[...this.pendingRunCreations].map((X)=>X.then(()=>{}))]),Y=[...this.runs.values()].flatMap((X)=>[...X.handles.values()]),V=Q.some((X)=>X.status==="rejected")?[]:await Promise.allSettled(Y.map((X)=>X.cancel($)));nY([...Q,...V]);for(let X of new Set([...this.runs.values()].map((z)=>z.snapshot.chatId)))await this.presentation.closeChat(X)}assertAcceptingRuns(){if(this.shuttingDown)throw Error("Agent service is shutting down; cannot start new runs")}createRun($,Z,J){let Q=this.createRunInternal($,Z,J);return this.pendingRunCreations.add(Q),Q.then(()=>this.pendingRunCreations.delete(Q),()=>this.pendingRunCreations.delete(Q)),Q}async createRunInternal($,Z,J){let{owner:Q}=$,Y=J.resumeSessionId?aj(Q.workDir,Z.workDir):aY(Q.workDir,Z.workDir),V=m6(Y),X;if(J.parentRunId){if(X=this.runs.get(J.parentRunId),!X)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameOwner(X,$)}let z=$.codexAccountId,H=this.deps.getCatalog(z),G=Z.identityIds.map((L)=>{let P=H.identities.find((F)=>F.id===L);if(!P)throw Error(`agent identity not found: ${L}`);if(P.status!=="ready")throw Error(`${P.displayName}: ${P.reason??P.status}`);return P}),W=G.map((L)=>mR(L,pR(L,Z.effort),J.resumeSessionId)),K=`agent_${kR()}`,j={runId:K,codexAccountId:z,owner:{...Q},sessionName:Q.name,chatId:Q.chatId,sessionWorkDir:Q.workDir,...J.requestId?{requestId:J.requestId,requestHash:J.requestHash}:{},...Q.kind==="project"?{...Z.requesterOpenId?{requesterOpenId:Z.requesterOpenId}:{}}:{},workDir:Y,prompt:Z.prompt,description:Z9(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},...J.resumedFromRunId?{resumedFromRunId:J.resumedFromRunId}:{},depth:0,status:"queued",workers:W,createdAt:new Date().toISOString()},_={snapshot:j,context:$,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(j)}catch(L){if(this.runs.set(K,_),J.parentRunId)X?.children.add(K);let P=`Agent 卡片初始化失败,Agent 未启动: ${s0(L)}`;for(let F of W)F.status="failed",F.error=P;throw await this.finalizeRun(_,"failed",P),await this.deps.sendTextRaw(Q.chatId,`❌ ${P}`),L}if(this.runs.set(K,_),J.parentRunId)X?.children.add(K);if(this.shuttingDown||this.currentCancellationEpoch($)!==J.cancellationEpoch){_.cancelled=!0;let L="任务已在启动前取消";for(let P of _.snapshot.workers)P.status="cancelled",P.error=L,P.finishedAt=new Date().toISOString();return this.persist(_),await Promise.all(_.snapshot.workers.map((P)=>this.updateWorkerCard(_,P))),await this.finalizeRun(_,"cancelled",L),this.readSnapshot(_)}this.persist(_);for(let L of G){let P=J.resumeSessionId;this.executeWorker(_,L,Z.prompt,V,P).catch((F)=>{B(`agent: run=${K} worker=${L.id} crashed: ${s0(F)}`)})}return this.readSnapshot(_)}async executeWorker($,Z,J,Q,Y){let V=$.snapshot.workers.find((z)=>z.identityId===Z.id);if(await this.acquireSlot(Z,(z)=>{V.queuedReason=z,this.persist($),this.updateWorkerCard($,V)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let X="";try{if(X=bR(32).toString("base64url"),this.capabilities.set(X,{kind:"worker",context:$.context,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,X),V.status="running",V.startedAt=new Date().toISOString(),delete V.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,V),$.cancelled)return;this.assertSameOwner($,$.context);let z=Y?aj($.context.owner.workDir,$.snapshot.workDir):aY($.context.owner.workDir,$.snapshot.workDir);if(z!==$.snapshot.workDir||m6(z)!==Q)throw Error("agent work_dir changed before the worker could start");let H=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:V.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,projectBound:$.context.owner.kind==="project",...$.context.owner.kind==="session"?{developerInstructions:$.context.sessionInstructions(Z.provider)}:{},profile:uR(I9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:d2},hostEnv:{LODESTAR_AGENT_URL:c4(m.notify.bind,m.notify.port),LODESTAR_AGENT_CAPABILITY:X,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(W)=>{if($.cancelled)return;V.status="needs_input",V.pendingInput=W,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,V)},onProgress:(W)=>this.recordStep($,V,W),onCodexAccount:(W)=>{if($.cancelled)return;V.codexAccountId=W,this.persist($)},onSession:(W)=>{if(V.sessionId===W)return;V.sessionId=W,this.persist($)}}});$.handles.set(Z.id,H);let G=await H.done;if($.cancelled)return;if(this.clearProgressTimer($,Z.id),V.output=G.output,V.outputTruncated=G.outputTruncated,V.sessionId=G.sessionId,V.checkpointId=G.checkpointId,V.durationMs=G.durationMs,V.usage=G.usage,V.finishedAt=new Date().toISOString(),delete V.pendingInput,$.cancelled)return;V.status="completed",this.persist($),await this.updateWorkerCard($,V)}catch(z){if(z instanceof m3){if(V.output=z.output,V.outputTruncated=!1,z.sessionId)V.sessionId=z.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),V.status="failed",V.error=s0(z),V.finishedAt=new Date().toISOString(),V.startedAt)V.durationMs=Date.now()-Date.parse(V.startedAt);delete V.pendingInput,this.persist($),await this.updateWorkerCard($,V)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(X)this.capabilities.delete(X);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||c3(Z.status))return;if(Z.steps.push(J),Z.steps.length>dj)Z.steps.splice(0,Z.steps.length-dj);if($.progressTimers.has(Z.identityId))return;let Q=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z,"progress")},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: ${s0(Q)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${s0(Q)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${s0(Q)}`).catch((Y)=>B(`agent: terminal failure delivery failed: ${s0(Y)}`))})}async cancelTree($,Z){let J=!p3($.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((z)=>this.runs.get(z)).filter((z)=>!!z&&this.treeHasActiveRun(z));if(V.length===0)break;let X=await Promise.allSettled(V.map((z)=>this.cancelTree(z,Z)));if(Q.push(...X),X.some((z)=>z.status==="rejected"))break}if(!J){nY(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=$_(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: ${s0(X)}`)),V}let Y=[];for(let V of $.snapshot.workers)if(!c3(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: ${s0(Q)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Q=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
583
+ `),allowDelegation:!1,allowUserInput:!$.projectBound,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return pR(Q,$.prompt,$.callbacks,void 0,$.resumeSessionId,!$.projectBound)}function pR($,Z,J={},Q=kX,Y,V=!0){let X=[],z=null,H=!1,G=null,W=null,K=[],j,_,D=Date.now(),P=new Promise((N,y)=>{j=N,_=y}),L=(N)=>{if(!N)return null;try{if(!Y||N!==Y)Q($.provider,N);if(Y&&N!==Y)throw Error(`native resume returned session ${N}, expected ${Y}; refusing to treat it as a resumed conversation`);return J.onSession?.(N),null}catch(y){return y instanceof Error?y:Error(String(y))}},F=()=>{if($.off("assistant_text",A),$.off("tool_use",O),$.off("tool_result",T),$.off("subagent_step",k),$.off("can_use_tool",E),$.off("hook_callback",f),$.off("init",d),!$.isAlive())$.off("error",S);$.off("turn_retry",V0),$.off("codex_account_changed",g),$.off("result",e),$.off("exit",c)},U=(N,y)=>{if(G)return G;return H=!0,K.length=0,G=Promise.resolve().then(async()=>{let p=L($.sessionId);try{await $.kill(3000)}catch(a1){W=a1 instanceof Error?a1:Error(String(a1))}F();let J0=[N,p,W].filter((a1)=>!!a1),k$=J0.length>1?AggregateError(J0,J0.map((a1)=>a1.message).join("; ")):J0[0];if(k$){_(new p3(k$,X.join("").trim(),$.sessionId));return}let n1=$.sessionId;if(!n1){_(new p3(Error("delegated agent completed without a native session id"),X.join("").trim(),null));return}let X9=X.join("").trim(),zV=uR(y?.checkpoint,$);j({output:X9,outputTruncated:!1,sessionId:n1,...zV?{checkpointId:zV}:{},durationMs:Date.now()-D,usage:$.lastUsage?{...$.lastUsage}:null})}),G},A=(N)=>{if(H||N?.parentToolUseId||typeof N?.text!=="string")return;X.push(N.text)},M=(N)=>{if(H)return;try{J.onProgress?.(N)}catch(y){U(y instanceof Error?y:Error(String(y)))}},O=(N)=>M({at:new Date().toISOString(),phase:"started",tool:String(N?.name??"tool"),detail:""}),T=(N)=>M({at:new Date().toISOString(),phase:"completed",tool:N?.is_error?"tool error":"tool result",detail:""}),k=(N)=>M({at:new Date().toISOString(),phase:N?.phase??"info",tool:String(N?.tool??"subagent"),detail:""}),E=(N)=>{if(H)return;if(N.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(N.request_id,"allow",{updatedInput:N.input??{}})}catch(p){U(p instanceof Error?p:Error(String(p)))}return}let y;try{if(y=cR(N),!V)throw Error(`${m2}: ${y.questions.map((p)=>p.question).join("; ")}`)}catch(p){U(p instanceof Error?p:Error(String(p)));return}if(K.some((p)=>p.request.requestId===y.requestId))return;K.push({request:y,originalInput:N.input??{}});try{if(K.length===1)J.onNeedsInput?.(y)}catch(p){U(p instanceof Error?p:Error(String(p)))}},f=(N)=>{if(H)return;try{$.sendHookResponse(String(N.request_id),{})}catch(y){U(y instanceof Error?y:Error(String(y)))}},d=(N)=>{let y=L(N?.session_id??$.sessionId);if(y)U(y)},S=(N)=>{z=N instanceof Error?N:Error(String(N))},g=(N)=>{if(H)return;try{J.onCodexAccount?.(N.accountId)}catch(y){U(y instanceof Error?y:Error(String(y)))}if(N.diagnostics.length)B(`agent-runner: selected Codex account=${N.accountId}; diagnostics: ${N.diagnostics.join(";")}`)},V0=(N)=>{M({at:new Date().toISOString(),phase:"info",tool:N.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:N.phase==="waiting"?`${N.message} · ${N.delayMs/1000}s 后重试 #${N.attempt}`:`正在重试 #${N.attempt}`})},e=(N)=>{let y=N?.is_error?Error(String(N.error??N.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;U(y,N)},c=(N)=>{if(H)return;let y=`code=${N?.code??"null"} signal=${N?.signal??"null"}`;U(z??Error(`delegated agent exited before result (${y})`))};$.on("assistant_text",A),$.on("tool_use",O),$.on("tool_result",T),$.on("subagent_step",k),$.on("can_use_tool",E),$.on("hook_callback",f),$.on("init",d),$.on("error",S),$.on("turn_retry",V0),$.on("codex_account_changed",g),$.on("result",e),$.on("exit",c);try{$.sendInitialize(),$.sendUserText(Z)}catch(N){U(N instanceof Error?N:Error(String(N)))}return{done:P,isAlive:()=>$.isAlive(),pendingInput:()=>K[0]?.request??null,answer(N,y){let p=K[0];if(!p)throw Error("delegated agent is not waiting for input");if(p.request.requestId!==N)throw Error(`delegated agent input request mismatch: expected ${p.request.requestId}`);if($.sendPermissionResponse(N,"allow",{updatedInput:{...p.originalInput,answers:y}}),K.shift(),K[0])J.onNeedsInput?.(K[0].request)},async cancel(N="delegated agent cancelled"){let y=H;if(await U(Error(N)),await P.catch(()=>{}),y){if($.isAlive())await $.kill(3000);W=null,F()}if(W)throw W}}}function cR($){let Z=$.input??{},Q=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Y,V)=>lR(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 lR($,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 z=X&&typeof X==="object"?X:{};return{label:String(z.label??z.value??""),...z.description?{description:String(z.description)}:{}}}).filter((X)=>X.label):[];return{id:Y,...J.header?{header:String(J.header)}:{},question:Q,options:V}}function uR($,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 p3;var aj=R(()=>{JQ();D9();z0();dY();h();p3=class p3 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});function W$($){if($.kind!=="session")return $.context;let Z=$.session;return{owner:{kind:"session",name:Z.sessionName,chatId:Z.chatId,workDir:Z.workDir},codexAccountId:Z.codexAccountId(),sessionInstructions:(J)=>Z.delegatedAgentDeveloperInstructions(J)}}import{createHash as oj,randomBytes as dR,randomUUID as iR}from"node:crypto";import{existsSync as nR,readdirSync as aR,readFileSync as V_,realpathSync as p6,statSync as oR}from"node:fs";import{isAbsolute as sR,join as c6,relative as tR,resolve as X_,sep as rR}from"node:path";class sY{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;pendingRunCreations=new Set;requests=new Map;shuttingDown=!1;constructor($=eR){this.deps=$;this.presentation=new E3($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}projectPrincipal($){if($.owner.kind!=="project")throw Error("project principal requires project ownership");return{kind:"project",context:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}startRun($,Z){return this.withRequestId($,Z,"run",(J)=>this.startRunOnce($,Z,J))}async startRunOnce($,Z,J){if(this.assertAcceptingRuns(),$.kind==="worker")throw Error(nY);if(Z9(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 Y=this.findSessionHistory($,Z.sessionId),V=Z.identityIds[0]?this.requireIdentity($,Z.identityIds[0]):void 0;return this.resumeRun($,Z,J,Y,V)}let Q=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun(W$($),Z,{...J,cancellationEpoch:this.currentCancellationEpoch(W$($))})}finally{Q()}}followUp($,Z,J){return this.withRequestId($,J,`follow-up:${Z}`,(Q)=>this.followUpOnce($,Z,J,Q))}async followUpOnce($,Z,J,Q){if(this.assertAcceptingRuns(),$.kind==="worker")throw Error(nY);Z9(J.description);let Y=this.runs.get(Z);if(!Y)throw Error(`agent run not found: ${Z}`);this.assertResumeProject($,Y);let V=Y.snapshot.workers.length===1?Y.snapshot.workers[0]:J_(Y.snapshot,J.identityId);if(Y.handles.get(V.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!V.sessionId)throw Error(`${V.identityName} has no resumable native session id`);this.findSessionHistory($,V.sessionId);let X=J.identityId?this.requireIdentity($,J.identityId):void 0;return this.resumeRun($,{...J,identityIds:J.identityId?[J.identityId]:[],sessionId:V.sessionId},Q,{run:Y,worker:V},X)}requireIdentity($,Z){let J=this.deps.getCatalog(W$($).codexAccountId).identities.find((Q)=>Q.id===Z);if(!J)throw Error(`agent identity not found: ${Z}`);if(J.status!=="ready")throw Error(`${J.displayName}: ${J.reason??J.status}`);return J}async resumeRun($,Z,J,Q,Y){let V=W$($);this.assertResumeProject($,Q.run);let X=Y??this.requireIdentity($,Q.worker.identityId);if(X.provider!==Q.worker.provider)throw Error("native session belongs to a different Agent backend");let z=q1(o0(Q.run.snapshot))===q1(V.owner),H=Z.effort??(Q.worker.identityId===X.id?Q.worker.effort:void 0),G=Z.workDir??Q.run.snapshot.workDir,W=this.reserveCapacity($,1),K;try{return K=this.reserveNativeSession({provider:X.provider,sessionId:Z.sessionId}),await this.createRun(V,{identityIds:[X.id],description:Z.description,prompt:Z.prompt,effort:H,workDir:G,requesterOpenId:Z.requesterOpenId??(z?Q.run.snapshot.requesterOpenId:void 0)},{...J,...z?{parentRunId:Q.run.snapshot.runId,parentKind:"follow_up"}:{},resumedFromRunId:Q.run.snapshot.runId,cancellationEpoch:this.currentCancellationEpoch(V),resumeSessionId:Z.sessionId})}finally{K?.(),W()}}async answer($,Z,J){if($.kind==="project")throw Error(m2);let Q=this.requireMutableDescendant($,Z),Y=J_(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)=>o0(V.snapshot).kind==="session"&&V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Y=await Promise.allSettled(Q.map((V)=>this.cancelTree(V,J)));aY(Y)}async cancelProjectRunFromCard($,Z,J,Q){let Y=this.runs.get($);if(!Y||o0(Y.snapshot).kind!=="project"||!Q||!J||Y.snapshot.chatId!==Z||Y.snapshot.cardMessageId!==J)throw Error("项目任务卡片无效或不属于当前群");return this.cancelRun(this.projectPrincipal({owner:o0(Y.snapshot)}),$,"用户通过项目任务卡取消")}async withRequestId($,Z,J,Q){if($.kind==="worker")throw Error(nY);if((Z.requestId||Z.requesterOpenId)&&$.kind!=="project")throw Error("request_id and requester_open_id require explicit project mode");if(!Z.requestId)return Q({});let Y=q1(W$($).owner),V=JSON.stringify([Y,Z.requestId]),X=oj("sha256").update(JSON.stringify({operation:J,prompt:Z.prompt,description:Z.description,effort:Z.effort,workDir:Z.workDir,requesterOpenId:Z.requesterOpenId,identityIds:"identityIds"in Z?Z.identityIds:void 0,identityId:"identityId"in Z?Z.identityId:void 0,sessionId:"sessionId"in Z?Z.sessionId:void 0})).digest("hex"),z=[...this.runs.values()].find((W)=>W.snapshot.requestId===Z.requestId&&q1(o0(W.snapshot))===Y);if(z){if(z.snapshot.requestHash!==X)throw Error("request_id was already used with different input");return this.readSnapshot(z)}let H=this.requests.get(V);if(H){if(H.hash!==X)throw Error("request_id is in use with different input");return H.promise}let G=Promise.resolve().then(()=>Q({requestId:Z.requestId,requestHash:X}));this.requests.set(V,{hash:X,promise:G});try{return await G}finally{this.requests.delete(V)}}async shutdown($){this.shuttingDown=!0;let Z=new Set([...this.runs.values()].map((X)=>`${X.snapshot.sessionName}\x00${X.snapshot.chatId}`));for(let X of Z){let[z,H]=X.split("\x00");this.bumpCancellationEpoch(z,H)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Q=await Promise.allSettled([...J.map((X)=>this.cancelTree(X,$)),...[...this.pendingRunCreations].map((X)=>X.then(()=>{}))]),Y=[...this.runs.values()].flatMap((X)=>[...X.handles.values()]),V=Q.some((X)=>X.status==="rejected")?[]:await Promise.allSettled(Y.map((X)=>X.cancel($)));aY([...Q,...V]);for(let X of new Set([...this.runs.values()].map((z)=>z.snapshot.chatId)))await this.presentation.closeChat(X)}assertAcceptingRuns(){if(this.shuttingDown)throw Error("Agent service is shutting down; cannot start new runs")}createRun($,Z,J){let Q=this.createRunInternal($,Z,J);return this.pendingRunCreations.add(Q),Q.then(()=>this.pendingRunCreations.delete(Q),()=>this.pendingRunCreations.delete(Q)),Q}async createRunInternal($,Z,J){let{owner:Q}=$,Y=J.resumeSessionId?Z_(Q.workDir,Z.workDir):oY(Q.workDir,Z.workDir),V=p6(Y),X;if(J.parentRunId){if(X=this.runs.get(J.parentRunId),!X)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameOwner(X,$)}let z=$.codexAccountId,H=this.deps.getCatalog(z),G=Z.identityIds.map((P)=>{let L=H.identities.find((F)=>F.id===P);if(!L)throw Error(`agent identity not found: ${P}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),W=G.map((P)=>$T(P,ZT(P,Z.effort),J.resumeSessionId)),K=`agent_${iR()}`,j={runId:K,codexAccountId:z,owner:{...Q},sessionName:Q.name,chatId:Q.chatId,sessionWorkDir:Q.workDir,...J.requestId?{requestId:J.requestId,requestHash:J.requestHash}:{},...Q.kind==="project"?{...Z.requesterOpenId?{requesterOpenId:Z.requesterOpenId}:{}}:{},workDir:Y,prompt:Z.prompt,description:Z9(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},...J.resumedFromRunId?{resumedFromRunId:J.resumedFromRunId}:{},depth:0,status:"queued",workers:W,createdAt:new Date().toISOString()},_={snapshot:j,context:$,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(j)}catch(P){if(this.runs.set(K,_),J.parentRunId)X?.children.add(K);let L=`Agent 卡片初始化失败,Agent 未启动: ${s0(P)}`;for(let F of W)F.status="failed",F.error=L;throw await this.finalizeRun(_,"failed",L),await this.deps.sendTextRaw(Q.chatId,`❌ ${L}`),P}if(this.runs.set(K,_),J.parentRunId)X?.children.add(K);if(this.shuttingDown||this.currentCancellationEpoch($)!==J.cancellationEpoch){_.cancelled=!0;let P="任务已在启动前取消";for(let L of _.snapshot.workers)L.status="cancelled",L.error=P,L.finishedAt=new Date().toISOString();return this.persist(_),await Promise.all(_.snapshot.workers.map((L)=>this.updateWorkerCard(_,L))),await this.finalizeRun(_,"cancelled",P),this.readSnapshot(_)}this.persist(_);for(let P of G){let L=J.resumeSessionId;this.executeWorker(_,P,Z.prompt,V,L).catch((F)=>{B(`agent: run=${K} worker=${P.id} crashed: ${s0(F)}`)})}return this.readSnapshot(_)}async executeWorker($,Z,J,Q,Y){let V=$.snapshot.workers.find((z)=>z.identityId===Z.id);if(await this.acquireSlot(Z,(z)=>{V.queuedReason=z,this.persist($),this.updateWorkerCard($,V)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let X="";try{if(X=dR(32).toString("base64url"),this.capabilities.set(X,{kind:"worker",context:$.context,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,X),V.status="running",V.startedAt=new Date().toISOString(),delete V.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,V),$.cancelled)return;this.assertSameOwner($,$.context);let z=Y?Z_($.context.owner.workDir,$.snapshot.workDir):oY($.context.owner.workDir,$.snapshot.workDir);if(z!==$.snapshot.workDir||p6(z)!==Q)throw Error("agent work_dir changed before the worker could start");let H=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:V.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,projectBound:$.context.owner.kind==="project",...$.context.owner.kind==="session"?{developerInstructions:$.context.sessionInstructions(Z.provider)}:{},profile:YT(g9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:d2},hostEnv:{LODESTAR_AGENT_URL:c4(m.notify.bind,m.notify.port),LODESTAR_AGENT_CAPABILITY:X,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(W)=>{if($.cancelled)return;if($.context.owner.kind==="project")throw Error(m2);V.status="needs_input",V.pendingInput=W,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,V)},onProgress:(W)=>this.recordStep($,V,W),onCodexAccount:(W)=>{if($.cancelled)return;V.codexAccountId=W,this.persist($)},onSession:(W)=>{if(V.sessionId===W)return;V.sessionId=W,this.persist($)}}});$.handles.set(Z.id,H);let G=await H.done;if($.cancelled)return;if(this.clearProgressTimer($,Z.id),V.output=G.output,V.outputTruncated=G.outputTruncated,V.sessionId=G.sessionId,V.checkpointId=G.checkpointId,V.durationMs=G.durationMs,V.usage=G.usage,V.finishedAt=new Date().toISOString(),delete V.pendingInput,$.cancelled)return;V.status="completed",this.persist($),await this.updateWorkerCard($,V)}catch(z){if(z instanceof p3){if(V.output=z.output,V.outputTruncated=!1,z.sessionId)V.sessionId=z.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),V.status="failed",V.error=s0(z),V.finishedAt=new Date().toISOString(),V.startedAt)V.durationMs=Date.now()-Date.parse(V.startedAt);delete V.pendingInput,this.persist($),await this.updateWorkerCard($,V)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(X)this.capabilities.delete(X);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||l3(Z.status))return;if(Z.steps.push(J),Z.steps.length>rj)Z.steps.splice(0,Z.steps.length-rj);if($.progressTimers.has(Z.identityId))return;let Q=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z,"progress")},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: ${s0(Q)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${s0(Q)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${s0(Q)}`).catch((Y)=>B(`agent: terminal failure delivery failed: ${s0(Y)}`))})}async cancelTree($,Z){let J=!c3($.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((z)=>this.runs.get(z)).filter((z)=>!!z&&this.treeHasActiveRun(z));if(V.length===0)break;let X=await Promise.allSettled(V.map((z)=>this.cancelTree(z,Z)));if(Q.push(...X),X.some((z)=>z.status==="rejected"))break}if(!J){aY(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=z_(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: ${s0(X)}`)),V}let Y=[];for(let V of $.snapshot.workers)if(!l3(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: ${s0(Q)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Q=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
583
584
  `),Y=Q.length>3000?`${Q.slice(0,3000)}
584
585
  …完整错误已保存在任务记录中。`:Q;await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ 委派卡片出现更新错误 · ${$.snapshot.description??$.snapshot.runId}
585
586
  结果已保存,卡片更新期间出现 ${$.snapshot.presentationErrors.length} 个错误:
586
587
  ${Y}
587
- 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${s0(V)}`))}}async updateWorkerCard($,Z,J="state"){if($.finalized)return;let Q=$.snapshot.cardMessageId;try{await this.presentation.update($.snapshot,!1,J==="progress")}catch(Y){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${s0(Y)}`)}finally{if($.snapshot.cardMessageId!==Q)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=cj("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Q}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=sj($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(p6(a1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;Q_(Z),this.deps.writeTextArtifact(p6(a1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=sj($.snapshot);if($.artifactsUnloaded)Z_(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.assertSameOwner(J,W$($)),!J.context)J.context=W$($);return J}assertResumeProject($,Z){let J=W$($).owner,Q=o0(Z.snapshot);if(J.chatId!==Q.chatId||Q$(J.workDir)!==Q$(Q.workDir))throw Error("agent session belongs to a different project or group; cross-project and cross-group resume is not allowed")}findSessionHistory($,Z){let J=[...this.runs.values()].flatMap((V)=>V.snapshot.workers.filter((X)=>X.sessionId===Z).map((X)=>({run:V,worker:X})));if(!J.length)throw Error("agent session project/group ownership is unknown; only registered sessions in this project and group can be resumed");for(let{run:V}of J)this.assertResumeProject($,V);if(new Set(J.map(({worker:V})=>V.provider)).size>1)throw Error("native session id has conflicting backend records; its unique identity cannot be established");let Q=new Set(J.flatMap(({run:V})=>[V.snapshot.resumedFromRunId,V.snapshot.parentRunId])),Y=J.filter(({run:V})=>!Q.has(V.snapshot.runId)).sort((V,X)=>Date.parse(X.run.snapshot.createdAt)-Date.parse(V.run.snapshot.createdAt))[0];if(!Y)throw Error(`agent session history has no latest run: ${Z}`);return Y}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!c3(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){let J=o0(Z.snapshot),Q=W$($).owner;if(J.kind!==Q.kind||J.name!==Q.name||J.chatId!==Q.chatId)return!1;if($.kind!=="worker")return!0;let Y=Z;while(Y){if(Y.snapshot.runId===$.runId)return!0;Y=Y.snapshot.parentRunId?this.runs.get(Y.snapshot.parentRunId):void 0}return!1}assertSameOwner($,Z){if(q1(o0($.snapshot))!==q1(Z.owner))throw Error("agent run belongs to a different Session or project")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!p3($.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=q1(W$($).owner),Q=[...this.runs.values()].filter((z)=>q1(o0(z.snapshot))===J&&(!p3(z.snapshot.status)||z.handles.size>0)).length,Y=this.startingRunsBySession.get(J)??0;if(Q+Y>=ij)throw Error(`${$.kind==="project"?"Project":"Session"} has reached ${ij} active Agent runs`);if([...this.runs.values()].reduce((z,H)=>z+H.snapshot.workers.filter((G)=>!c3(G.status)||H.handles.get(G.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>nj)throw Error(`global Agent worker limit ${nj} 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),tj(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){if($.owner.kind==="project")return 0;return this.cancellationEpochBySession.get(this.sessionKey($.owner.name,$.owner.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}tryAcquireSlot($){let Z=lj.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=dY||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=lj.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${dY} 个 Agent)`),new Promise((Q)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Q}))}releaseSlot($){this.activeTurns--,tj(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<dY;){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(!p3($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!c3(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,context: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<=uj)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&p3(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-uj))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function aY($,Z){let J=m6($),Q=m6(ej($,Z===void 0?".":g6(Z))),Y=hR(J,Q);if(Y===".."||Y.startsWith(`..${IR}`)||fR(Y))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!yR(Q).isDirectory())throw Error(`agent work_dir is not a directory: ${Q}`);return Y===""?$:Q}function aj($,Z){let J=Z===void 0?$:ej($,g6(Z));return aY($,J),J}function mR($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function pR($,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 oj($,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 p3($){return $==="completed"||$==="failed"||$==="cancelled"}function c3($){return $==="completed"||$==="failed"||$==="cancelled"}function sj($){return JSON.parse(JSON.stringify($))}function cR(){if(!wR(a1))return[];let $=[];for(let Z of vR(a1).filter((J)=>J.endsWith(".json")).sort()){let J=p6(a1,Z),Q;try{Q=JSON.parse(rj(J,"utf8"))}catch(Y){throw Error(`agent run artifact is unreadable (${J}): ${s0(Y)}`)}if(!lR(Q))throw Error(`agent run artifact is invalid: ${J}`);Z_(Q,J),$.push(Q)}return $}function lR($){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.owner===void 0||!!Z.owner&&["session","project"].includes(Z.owner.kind)&&Z.owner.name===Z.sessionName&&Z.owner.chatId===Z.chatId&&typeof Z.owner.workDir==="string"&&Z.owner.workDir===Z.sessionWorkDir)&&(Z.resumedFromRunId===void 0||typeof Z.resumedFromRunId==="string")&&(Z.requestId===void 0||typeof Z.requestId==="string"&&typeof Z.requestHash==="string")&&(Z.deliveryMode===void 0||Z.deliveryMode==="chat"||Z.deliveryMode==="drive")&&(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 $_($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(s0).join("; ")}`)}function nY($){if($.some((Z)=>Z.status==="rejected"))throw $_($)}function s0($){return $ instanceof Error?$.message:String($)}function uR($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function Z_($,Z,J=J_){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 J_($,Z){Q_($);try{return rj(p6(a1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${s0(J)}`)}}function Q_($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function tj($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var dY=8,lj,iY="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",uj=512,dj=50,ij=64,nj=128,gR;var Y_=N(()=>{rQ();$Y();$0();f0();N6();pj();U4();H0();x0();h();lj=new Map([["openrouter",2]]),gR={...eQ,getCatalog:v3,startWorker:mj,sendTextRaw:I,writeArtifact:a,writeTextArtifact:r0,readTextArtifact:J_,loadArtifacts:cR}});import{randomBytes as dR,timingSafeEqual as iR}from"node:crypto";function V_($,Z=BV){let J={baseUrl:$,capability:dR(32).toString("base64url")};return a(Z,J),J}function X_($,Z){let J=Buffer.from(Z),Q=Buffer.from($.capability);return J.length===Q.length&&iR(J,Q)}var z_=N(()=>{H0();x0()});import{realpathSync as nR,statSync as aR}from"node:fs";function H_($,Z=Z0){let J=$.trim();if(!J||Z.sanitizeSessionName(J)!==J||RZ(J)!==J)throw Error("请指定项目或 worktree 名称,不能指定 BTW/FK 临时会话");let Q=Z.chatIdForSession(J);if(!Q)throw Error(`项目 ${J} 没有明确的群绑定`);let Y=nR(Z.resolveProjectDir(J));if(!aR(Y).isDirectory())throw Error(`项目工作目录不是文件夹: ${Y}`);return{owner:{kind:"project",name:J,chatId:Q,workDir:Y}}}var G_=N(()=>{$0();U4()});async function W_($,Z,J,Q){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Y=(W,K)=>{return Z.statusCode=W,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},V=tR($.headers.authorization);if(!V)return Y(401,{error:"missing bearer capability"});let X;try{let W=J.searchParams.getAll("project");if(W.length>1||W.length&&!W[0].trim())return Y(400,{error:"invalid project selector"});X=W.length?Q.authorizeProject?.(V,W[0])??null:oR(Q,V)}catch(W){return Y(409,{error:rY(W)})}if(!X)return Y(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return Y(200,rR(await XB(W$(X).codexAccountId)));if($.method==="POST"&&J.pathname==="/agents/runs")try{let W=await Q.service.startRun(X,xj(await tY($)));return Y(202,c6(W))}catch(W){return Y(409,{error:rY(W)})}let z=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!z)return Y(405,{error:"unsupported agent endpoint"});let H=sR(z[1]);if(!H)return Y(400,{error:"invalid agent run id encoding"});let G=z[2];try{if(!G&&$.method==="GET")return Y(200,c6(Q.service.getRun(X,H)));if(!G&&$.method==="DELETE"){let W=await Q.service.cancelRun(X,H,"cancelled by agent client");return Y(W?200:409,W?{ok:!0,run_id:H}:{error:"agent run is already terminal",run_id:H})}if(G==="follow-up"&&$.method==="POST"){let W=await Q.service.followUp(X,H,Sj(await tY($)));return Y(202,c6(W))}if(G==="answer"&&$.method==="POST"){let W=await Q.service.answer(X,H,kj(await tY($)));return Y(200,c6(W))}}catch(W){return Y(409,{error:rY(W)})}return Y(405,{error:"unsupported agent endpoint"})}function oR($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function sR($){try{return decodeURIComponent($)}catch{return null}}function tR($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function tY($){let Z="",J=0;$.setEncoding("utf8");for await(let Q of $)if(J+=Buffer.byteLength(Q),J<=sY)Z+=Q;else Z="";if(J>sY)throw Error(`request body exceeds ${sY} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function rR($){return{catalog_generation:$.catalogGeneration,identities:$.identities.map((Z)=>({id:Z.id,display_name:Z.displayName,token_source_id:Z.tokenSourceId,token_source_display:Z.tokenSourceDisplay,provider:Z.provider,model:Z.model,model_display:Z.modelDisplay,default_effort:Z.defaultEffort,supported_efforts:Z.supportedEfforts,source_default:Z.sourceDefault,status:Z.status,reason:Z.reason})),source_failures:$.sourceFailures.map((Z)=>({token_source_id:Z.tokenSourceId,display:Z.display,status:Z.status,reason:Z.reason}))}}function c6($){return{run_id:$.runId,binding:o0($).kind,...o0($).kind==="project"?{project:o0($).name}:{session_name:$.sessionName},...$.requestId?{request_id:$.requestId}:{},work_dir:$.workDir,prompt:$.prompt,description:$.description,parent_run_id:$.parentRunId,resumed_from_run_id:$.resumedFromRunId,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 rY($){return $ instanceof Error?$.message:String($)}var sY=4194304;var K_=N(()=>{N6()});import{chmodSync as eR,existsSync as eY,readFileSync as __,realpathSync as $T,unlinkSync as ZT}from"node:fs";import{homedir as JT}from"node:os";import{basename as QT,dirname as YT,join as d1,resolve as VT}from"node:path";function XT($={}){let Z=$T(VT($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Q=$.exists??eY,Y=YT(Z),V=d1(Y,"src","agent-cli.ts"),X=d1(Y,"lodestar-agent.js"),z=d1(Y,"dist","lodestar-agent.js"),G=/^bun(?:\.exe)?$/i.test(QT(J))?[V,X,z]:[X,z],W=G.find(Q);if(!W)throw Error(`lodestar-agent entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:W}}function P_($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??HT(Z,$.homeDir??JT(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??XT(),V=d1(Q,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${j_(Y.runtime)}" "${j_(Y.entry)}" %*\r
588
+ 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${s0(V)}`))}}async updateWorkerCard($,Z,J="state"){if($.finalized)return;let Q=$.snapshot.cardMessageId;try{await this.presentation.update($.snapshot,!1,J==="progress")}catch(Y){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${s0(Y)}`)}finally{if($.snapshot.cardMessageId!==Q)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=oj("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Q}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=Q_($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(c6(o1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;W_(Z),this.deps.writeTextArtifact(c6(o1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=Q_($.snapshot);if($.artifactsUnloaded)H_(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.assertSameOwner(J,W$($)),!J.context)J.context=W$($);return J}assertResumeProject($,Z){let J=W$($).owner,Q=o0(Z.snapshot);if(J.chatId!==Q.chatId||Q$(J.workDir)!==Q$(Q.workDir))throw Error("agent session belongs to a different project or group; cross-project and cross-group resume is not allowed")}findSessionHistory($,Z){let J=[...this.runs.values()].flatMap((V)=>V.snapshot.workers.filter((X)=>X.sessionId===Z).map((X)=>({run:V,worker:X})));if(!J.length)throw Error("agent session project/group ownership is unknown; only registered sessions in this project and group can be resumed");for(let{run:V}of J)this.assertResumeProject($,V);if(new Set(J.map(({worker:V})=>V.provider)).size>1)throw Error("native session id has conflicting backend records; its unique identity cannot be established");let Q=new Set(J.flatMap(({run:V})=>[V.snapshot.resumedFromRunId,V.snapshot.parentRunId])),Y=J.filter(({run:V})=>!Q.has(V.snapshot.runId)).sort((V,X)=>Date.parse(X.run.snapshot.createdAt)-Date.parse(V.run.snapshot.createdAt))[0];if(!Y)throw Error(`agent session history has no latest run: ${Z}`);return Y}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!l3(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){let J=o0(Z.snapshot),Q=W$($).owner;if(J.kind!==Q.kind||J.name!==Q.name||J.chatId!==Q.chatId)return!1;if($.kind!=="worker")return!0;let Y=Z;while(Y){if(Y.snapshot.runId===$.runId)return!0;Y=Y.snapshot.parentRunId?this.runs.get(Y.snapshot.parentRunId):void 0}return!1}assertSameOwner($,Z){if(q1(o0($.snapshot))!==q1(Z.owner))throw Error("agent run belongs to a different Session or project")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!c3($.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=q1(W$($).owner),Q=[...this.runs.values()].filter((z)=>q1(o0(z.snapshot))===J&&(!c3(z.snapshot.status)||z.handles.size>0)).length,Y=this.startingRunsBySession.get(J)??0;if(Q+Y>=ej)throw Error(`${$.kind==="project"?"Project":"Session"} has reached ${ej} active Agent runs`);if([...this.runs.values()].reduce((z,H)=>z+H.snapshot.workers.filter((G)=>!l3(G.status)||H.handles.get(G.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>$_)throw Error(`global Agent worker limit ${$_} 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),Y_(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){if($.owner.kind==="project")return 0;return this.cancellationEpochBySession.get(this.sessionKey($.owner.name,$.owner.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}tryAcquireSlot($){let Z=sj.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=iY||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=sj.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${iY} 个 Agent)`),new Promise((Q)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Q}))}releaseSlot($){this.activeTurns--,Y_(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<iY;){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(!c3($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!l3(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,context: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<=tj)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&c3(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-tj))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function oY($,Z){let J=p6($),Q=p6(X_($,Z===void 0?".":m6(Z))),Y=tR(J,Q);if(Y===".."||Y.startsWith(`..${rR}`)||sR(Y))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!oR(Q).isDirectory())throw Error(`agent work_dir is not a directory: ${Q}`);return Y===""?$:Q}function Z_($,Z){let J=Z===void 0?$:X_($,m6(Z));return oY($,J),J}function $T($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function ZT($,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 J_($,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 c3($){return $==="completed"||$==="failed"||$==="cancelled"}function l3($){return $==="completed"||$==="failed"||$==="cancelled"}function Q_($){return JSON.parse(JSON.stringify($))}function JT(){if(!nR(o1))return[];let $=[];for(let Z of aR(o1).filter((J)=>J.endsWith(".json")).sort()){let J=c6(o1,Z),Q;try{Q=JSON.parse(V_(J,"utf8"))}catch(Y){throw Error(`agent run artifact is unreadable (${J}): ${s0(Y)}`)}if(!QT(Q))throw Error(`agent run artifact is invalid: ${J}`);H_(Q,J),$.push(Q)}return $}function QT($){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.owner===void 0||!!Z.owner&&["session","project"].includes(Z.owner.kind)&&Z.owner.name===Z.sessionName&&Z.owner.chatId===Z.chatId&&typeof Z.owner.workDir==="string"&&Z.owner.workDir===Z.sessionWorkDir)&&(Z.resumedFromRunId===void 0||typeof Z.resumedFromRunId==="string")&&(Z.requestId===void 0||typeof Z.requestId==="string"&&typeof Z.requestHash==="string")&&(Z.deliveryMode===void 0||Z.deliveryMode==="chat"||Z.deliveryMode==="drive")&&(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 z_($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(s0).join("; ")}`)}function aY($){if($.some((Z)=>Z.status==="rejected"))throw z_($)}function s0($){return $ instanceof Error?$.message:String($)}function YT($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function H_($,Z,J=G_){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 G_($,Z){W_($);try{return V_(c6(o1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${s0(J)}`)}}function W_($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function Y_($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var iY=8,sj,nY="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",tj=512,rj=50,ej=64,$_=128,eR;var K_=R(()=>{eQ();ZY();$0();f0();R6();aj();U4();H0();x0();h();sj=new Map([["openrouter",2]]),eR={...$Y,getCatalog:y3,startWorker:nj,sendTextRaw:I,writeArtifact:a,writeTextArtifact:r0,readTextArtifact:G_,loadArtifacts:JT}});import{randomBytes as VT,timingSafeEqual as XT}from"node:crypto";function B_($,Z=_V){let J={baseUrl:$,capability:VT(32).toString("base64url")};return a(Z,J),J}function j_($,Z){let J=Buffer.from(Z),Q=Buffer.from($.capability);return J.length===Q.length&&XT(J,Q)}var __=R(()=>{H0();x0()});import{realpathSync as zT,statSync as HT}from"node:fs";function L_($,Z=Z0){let J=$.trim();if(!J||Z.sanitizeSessionName(J)!==J||TZ(J)!==J)throw Error("请指定项目或 worktree 名称,不能指定 BTW/FK 临时会话");let Q=Z.chatIdForSession(J);if(!Q)throw Error(`项目 ${J} 没有明确的群绑定`);let Y=zT(Z.resolveProjectDir(J));if(!HT(Y).isDirectory())throw Error(`项目工作目录不是文件夹: ${Y}`);return{owner:{kind:"project",name:J,chatId:Q,workDir:Y}}}var P_=R(()=>{$0();U4()});async function q_($,Z,J,Q){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Y=(W,K)=>{return Z.statusCode=W,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},V=KT($.headers.authorization);if(!V)return Y(401,{error:"missing bearer capability"});let X;try{let W=J.searchParams.getAll("project");if(W.length>1||W.length&&!W[0].trim())return Y(400,{error:"invalid project selector"});X=W.length?Q.authorizeProject?.(V,W[0])??null:GT(Q,V)}catch(W){return Y(409,{error:eY(W)})}if(!X)return Y(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return Y(200,BT(await jB(W$(X).codexAccountId)));if($.method==="POST"&&J.pathname==="/agents/runs")try{let W=await Q.service.startRun(X,yj(await rY($)));return Y(202,l6(W))}catch(W){return Y(409,{error:eY(W)})}let z=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!z)return Y(405,{error:"unsupported agent endpoint"});let H=WT(z[1]);if(!H)return Y(400,{error:"invalid agent run id encoding"});let G=z[2];try{if(!G&&$.method==="GET")return Y(200,l6(Q.service.getRun(X,H)));if(!G&&$.method==="DELETE"){let W=await Q.service.cancelRun(X,H,"cancelled by agent client");return Y(W?200:409,W?{ok:!0,run_id:H}:{error:"agent run is already terminal",run_id:H})}if(G==="follow-up"&&$.method==="POST"){let W=await Q.service.followUp(X,H,fj(await rY($)));return Y(202,l6(W))}if(G==="answer"&&$.method==="POST"){if(X.kind==="project")return Y(409,{error:m2});let W=await Q.service.answer(X,H,gj(await rY($)));return Y(200,l6(W))}}catch(W){return Y(409,{error:eY(W)})}return Y(405,{error:"unsupported agent endpoint"})}function GT($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function WT($){try{return decodeURIComponent($)}catch{return null}}function KT($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function rY($){let Z="",J=0;$.setEncoding("utf8");for await(let Q of $)if(J+=Buffer.byteLength(Q),J<=tY)Z+=Q;else Z="";if(J>tY)throw Error(`request body exceeds ${tY} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function BT($){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 l6($){return{run_id:$.runId,binding:o0($).kind,...o0($).kind==="project"?{project:o0($).name}:{session_name:$.sessionName},...$.requestId?{request_id:$.requestId}:{},work_dir:$.workDir,prompt:$.prompt,description:$.description,parent_run_id:$.parentRunId,resumed_from_run_id:$.resumedFromRunId,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 eY($){return $ instanceof Error?$.message:String($)}var tY=4194304;var D_=R(()=>{R6()});import{chmodSync as jT,existsSync as $V,readFileSync as M_,realpathSync as _T,unlinkSync as LT}from"node:fs";import{homedir as PT}from"node:os";import{basename as qT,dirname as DT,join as d1,resolve as FT}from"node:path";function UT($={}){let Z=_T(FT($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Q=$.exists??$V,Y=DT(Z),V=d1(Y,"src","agent-cli.ts"),X=d1(Y,"lodestar-agent.js"),z=d1(Y,"dist","lodestar-agent.js"),G=/^bun(?:\.exe)?$/i.test(qT(J))?[V,X,z]:[X,z],W=G.find(Q);if(!W)throw Error(`lodestar-agent entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:W}}function O_($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??OT(Z,$.homeDir??PT(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??UT(),V=d1(Q,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${U_(Y.runtime)}" "${U_(Y.entry)}" %*\r
588
589
  `:`#!/bin/sh
589
- exec ${B_(Y.runtime)} ${B_(Y.entry)} "$@"
590
- `,z=eY(V)?__(V,"utf8"):null;if(z!==X)lV(V,X),B(`command: ${z===null?"installed":"updated"} ${V}`);else eR(V,448);return GT(J,Q,Z),zT(Q,Z),V}function zT($,Z){let J=d1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!eY(J))return;try{let Q=__(J,"utf8");if(!Q.includes("lodestar-consult")&&!Q.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}ZT(J),B(`command: removed obsolete ${J}`)}catch(Q){B(`command: obsolete removal failed (${J}): ${Q}`)}}function HT($,Z,J){if($==="win32")return d1(J??d1(Z,"AppData","Local"),"Lodestar","bin");return d1(Z,".local","bin")}function GT($,Z,J){let Q=J==="win32"?Object.keys($).find((z)=>z.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",V=$[Q]??"",X=(z)=>J==="win32"?z.toLowerCase():z;if(V.split(Y).some((z)=>X(z)===X(Z)))return;$[Q]=V?`${Z}${Y}${V}`:Z}function B_($){return`'${$.replaceAll("'",`'"'"'`)}'`}function j_($){return $.replaceAll('"','""')}var L_=N(()=>{h();x0()});function q_($,Z,J){return $>0&&Z-$>J}async function D_($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function F_($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function $V($){return typeof $==="string"&&$.length>0?$:void 0}function U_($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=$V(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=$V(J.file_key);if(!Q)return null;let Y=$V(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function M_($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function O_($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class ZV{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 D1($){return $ instanceof Error?$.message:String($)}function A_($,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 N_($){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(M0(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(z){let H=D1(z);return $.log(`temp-session: create "${Y.chatName}" failed: ${H}`),{ok:!1,error:H}}let X=async()=>{let z=null;try{if($.registerTempSessionLease(Y.chatName,V.chatId),z=Z(V.chatId,Y.chatName),z.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(z.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${z.workDir}`);if(z.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await z.startForked(Y.launch,{announce:!1}):await z.start({announce:!1})))throw Error(`${z.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:V.chatId}}catch(H){let G=D1(H);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${G}`),z)try{await z.stop("临时群启动失败清理",{announce:!1})}catch(K){let j=D1(K);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:V.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${j}`}}if(!V.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let W;try{let K=await $.disbandChatForSessionExact(Y.chatName,V.chatId);W=A_(Y.chatName,V.chatId,K)}catch(K){let j=D1(K);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:V.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${j}`}}try{$.registry.delete(W),z?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(K){let j=D1(K);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${j}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(z){let H=D1(z);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${H}`),{ok:!1,chatId:V.chatId,error:`${H};临时群/session 仍保留`}}},disbandTempSession:async(Y,V)=>{let X=$.chatIdForSession(Y);if(!V||X!==V){let G=`临时群 chat_id 已变化: expected=${V||"-"} bound=${X??"-"}`;return $.log(`temp-session: disband identity rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}if(!$.hasTempSessionLease(Y,V)){let G=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}let z=$.registry.get(X);try{if(z)await z.stop("bye 解散",{announce:!1})}catch(G){let W=D1(G);return $.log(`temp-session: stop before disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};无法确认 Session 已停止,未执行删群`}}let H;try{let G=await $.disbandChatForSessionExact(Y,X);H=A_(Y,X,G)}catch(G){let W=D1(G);return $.log(`temp-session: disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};临时群/session 仍保留`}}try{return $.registry.delete(H),z?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(G){let W=D1(G);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${W}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${W}`}}}}}var R_=N(()=>{r1()});var bT={};import*as Y9 from"@larksuiteoapi/node-sdk";import{chmodSync as WT,existsSync as QV,mkdirSync as KT,readFileSync as BT,unlinkSync as u6,writeFileSync as jT}from"node:fs";import{dirname as _T}from"node:path";function V9($,Z){if(i1=Math.max(i1,Z),l6)return l6;t0=!0,GX();let J=R9.stop().then((Q)=>({status:"fulfilled",value:Q}),(Q)=>({status:"rejected",reason:Q}));S_?.(),F1.close();for(let Q of C$.values())Q.closeModelSettingsChanges();try{C_?.()}catch(Q){i1=1,B(`shutdown WebSocket close failed: ${Q}`)}try{m2.persist()}catch(Q){B(`shutdown alive marker write failed: ${Q}`),i1=1}return l6=(async()=>{B(`${$}: staged shutdown begin sessions=${C$.size}`);try{let Q=(async()=>{await O_(()=>[...F1.pending(),...k_,...wG()]),m2.freezeForShutdown();let z=await Promise.allSettled([Q9.shutdown(`daemon ${$}`),q2.shutdown()]),H=await Promise.allSettled([yJ()]),G=await Promise.allSettled([...C$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[await J,...z,...H,...G]})(),Y=null,V=new Promise((z)=>{Y=setTimeout(()=>z("deadline"),E_)}),X=await Promise.race([Q.then((z)=>{for(let H of z)if(H.status==="rejected")i1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),V]);if(Y)clearTimeout(Y);if(X==="deadline")i1=1,B(`${$}: shutdown deadline ${E_}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(Q){B(`${$}: staged shutdown failed: ${Q}`),i1=1}finally{b_(),process.exit(i1)}})(),l6}function YV($){return M_(k_,$)}function w_($,Z="ws"){if(t0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=LT.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 qT(){m2.persist()}function v_($,Z){return VV.sessionFor($,Z)}async function DT($){return await VV.createTempSession($)}async function FT($,Z){return await VV.disbandTempSession($,Z)}function UT($){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 z=[];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}~~`;z.push(W);break}case"a":{let W=String(G.href??""),K=String(G.text??W);z.push(`[${K}](${W})`);break}case"at":{let W=String(G.user_name??G.user_id??"");z.push(`@${W}`);break}case"code_inline":z.push(`\`${String(G.text??"")}\``);break;case"hr":z.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")z.push(G.text)}}let H=z.join("");if(H.trim())Q.push(H)}return{markdown:Q.join(`
590
+ exec ${F_(Y.runtime)} ${F_(Y.entry)} "$@"
591
+ `,z=$V(V)?M_(V,"utf8"):null;if(z!==X)dV(V,X),B(`command: ${z===null?"installed":"updated"} ${V}`);else jT(V,448);return AT(J,Q,Z),MT(Q,Z),V}function MT($,Z){let J=d1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!$V(J))return;try{let Q=M_(J,"utf8");if(!Q.includes("lodestar-consult")&&!Q.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}LT(J),B(`command: removed obsolete ${J}`)}catch(Q){B(`command: obsolete removal failed (${J}): ${Q}`)}}function OT($,Z,J){if($==="win32")return d1(J??d1(Z,"AppData","Local"),"Lodestar","bin");return d1(Z,".local","bin")}function AT($,Z,J){let Q=J==="win32"?Object.keys($).find((z)=>z.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",V=$[Q]??"",X=(z)=>J==="win32"?z.toLowerCase():z;if(V.split(Y).some((z)=>X(z)===X(Z)))return;$[Q]=V?`${Z}${Y}${V}`:Z}function F_($){return`'${$.replaceAll("'",`'"'"'`)}'`}function U_($){return $.replaceAll('"','""')}var A_=R(()=>{h();x0()});function N_($,Z,J){return $>0&&Z-$>J}async function R_($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function T_($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function ZV($){return typeof $==="string"&&$.length>0?$:void 0}function E_($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=ZV(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=ZV(J.file_key);if(!Q)return null;let Y=ZV(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function x_($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function S_($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class JV{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 D1($){return $ instanceof Error?$.message:String($)}function C_($,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 b_($){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(M0(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(z){let H=D1(z);return $.log(`temp-session: create "${Y.chatName}" failed: ${H}`),{ok:!1,error:H}}let X=async()=>{let z=null;try{if($.registerTempSessionLease(Y.chatName,V.chatId),z=Z(V.chatId,Y.chatName),z.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(z.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${z.workDir}`);if(z.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await z.startForked(Y.launch,{announce:!1}):await z.start({announce:!1})))throw Error(`${z.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:V.chatId}}catch(H){let G=D1(H);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${G}`),z)try{await z.stop("临时群启动失败清理",{announce:!1})}catch(K){let j=D1(K);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:V.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${j}`}}if(!V.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let W;try{let K=await $.disbandChatForSessionExact(Y.chatName,V.chatId);W=C_(Y.chatName,V.chatId,K)}catch(K){let j=D1(K);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,chatId:V.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${j}`}}try{$.registry.delete(W),z?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(K){let j=D1(K);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${j}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${j}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(z){let H=D1(z);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${H}`),{ok:!1,chatId:V.chatId,error:`${H};临时群/session 仍保留`}}},disbandTempSession:async(Y,V)=>{let X=$.chatIdForSession(Y);if(!V||X!==V){let G=`临时群 chat_id 已变化: expected=${V||"-"} bound=${X??"-"}`;return $.log(`temp-session: disband identity rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}if(!$.hasTempSessionLease(Y,V)){let G=`群 ${V} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Y}": ${G}`),{ok:!1,error:`${G};未执行停止或删群`}}let z=$.registry.get(X);try{if(z)await z.stop("bye 解散",{announce:!1})}catch(G){let W=D1(G);return $.log(`temp-session: stop before disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};无法确认 Session 已停止,未执行删群`}}let H;try{let G=await $.disbandChatForSessionExact(Y,X);H=C_(Y,X,G)}catch(G){let W=D1(G);return $.log(`temp-session: disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};临时群/session 仍保留`}}try{return $.registry.delete(H),z?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(G){let W=D1(G);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${W}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${W}`}}}}}var k_=R(()=>{e1()});var dT={};import*as Y9 from"@larksuiteoapi/node-sdk";import{chmodSync as NT,existsSync as YV,mkdirSync as RT,readFileSync as TT,unlinkSync as d6,writeFileSync as ET}from"node:fs";import{dirname as xT}from"node:path";function V9($,Z){if(i1=Math.max(i1,Z),u6)return u6;t0=!0,KX();let J=T9.stop().then((Q)=>({status:"fulfilled",value:Q}),(Q)=>({status:"rejected",reason:Q}));f_?.(),F1.close();for(let Q of C$.values())Q.closeModelSettingsChanges();try{h_?.()}catch(Q){i1=1,B(`shutdown WebSocket close failed: ${Q}`)}try{c2.persist()}catch(Q){B(`shutdown alive marker write failed: ${Q}`),i1=1}return u6=(async()=>{B(`${$}: staged shutdown begin sessions=${C$.size}`);try{let Q=(async()=>{await S_(()=>[...F1.pending(),...g_,...mG()]),c2.freezeForShutdown();let z=await Promise.allSettled([Q9.shutdown(`daemon ${$}`),D2.shutdown()]),H=await Promise.allSettled([fJ()]),G=await Promise.allSettled([...C$.values()].map((W)=>W.stop(`daemon ${$}`,{announce:!1})));return[await J,...z,...H,...G]})(),Y=null,V=new Promise((z)=>{Y=setTimeout(()=>z("deadline"),v_)}),X=await Promise.race([Q.then((z)=>{for(let H of z)if(H.status==="rejected")i1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),V]);if(Y)clearTimeout(Y);if(X==="deadline")i1=1,B(`${$}: shutdown deadline ${v_}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(Q){B(`${$}: staged shutdown failed: ${Q}`),i1=1}finally{I_(),process.exit(i1)}})(),u6}function VV($){return x_(g_,$)}function m_($,Z="ws"){if(t0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=CT.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 bT(){c2.persist()}function p_($,Z){return XV.sessionFor($,Z)}async function kT($){return await XV.createTempSession($)}async function wT($,Z){return await XV.disbandTempSession($,Z)}function vT($){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 z=[];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}~~`;z.push(W);break}case"a":{let W=String(G.href??""),K=String(G.text??W);z.push(`[${K}](${W})`);break}case"at":{let W=String(G.user_name??G.user_id??"");z.push(`@${W}`);break}case"code_inline":z.push(`\`${String(G.text??"")}\``);break;case"hr":z.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")z.push(G.text)}}let H=z.join("");if(H.trim())Q.push(H)}return{markdown:Q.join(`
591
592
 
592
- `),imageKeys:Z,fileKeys:J}}async function OT($,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&&J9.has(V))return;if(V){if(J9.add(V),J9.size>200){let A=[...J9];J9.clear();for(let M of A.slice(-100))J9.add(M)}}let X=Number(J.create_time??0);if(q_(X,Z,MT)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)X$(V,"CrossMark");return}let z=J.chat_id,H={};try{H=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?H.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{jT(i3,JSON.stringify({chat_id:z,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${z.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(M){B(`debug: seed context failed: ${M}`)}let A=G.slice(7);H.text=A,J.content=JSON.stringify(H)}let W=L0.get(z);if(!W)await p9(),W=L0.get(z);if(!W)W=await YJ(z)??void 0;if(!W){B(`unknown chat ${z}, dropping message`),await k(z,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=HJ(W);M4(K,z);let j=v_(z,K),_={};try{_=JSON.parse(J.content??"{}")}catch{}let D=J.message_type,L="",P=!1,F=[];if(D==="text")L=(_.text??"").trim();else if(D==="post"){let A=UT(_);P=A.imageKeys.length>0||A.fileKeys.length>0,L=A.markdown.trim();for(let M of A.imageKeys){let O=await c9(J.message_id,M,"image");if(O)F.push(O)}for(let M of A.fileKeys){let O=await c9(J.message_id,M.key,"file",M.name);if(O)F.push(O)}}if(D==="text"&&L){if(await j.runCommand(L,Y,V))return}if((D==="text"||D==="post")&&L&&!P&&await D_({reply:()=>d6.consume({chatId:z,openId:Y,messageId:V??"",text:L,createTime:X,parentId:J.parent_id}),hasQuestion:()=>j.hasPendingAsk(),answerQuestion:()=>j.onAskMessageAnswer(L,Y,V??"")}))return;if(D==="text"&&L&&await j.consumeModelCustomMessage(L,Y))return;let U=U_(D,_);if(U){let A=await c9(J.message_id,U.key,U.type,U.name);if(!A){await k(z,F_(D));return}if(F.push(A),!L&&U.displayText)L=U.displayText}if(!L&&F.length===0){B(`drop empty message ${V} type=${D}`);return}if(await j.onMultiMessageInbound(L,F,Y,V??""))return;await j.onUserMessage(L||"(empty)",F,Y,V??"")}function i6($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复",agent_project_cancel:"停止项目任务"}[$]??$}function AT($){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 t$($){let Z=W0($.card?O$($.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 x_($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Q=i6(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=AT(Z),z=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await E4(V,X);return}catch(_){B(`card-action: ${J} original-card update failed: ${_ instanceof Error?_.message:_}`),await g2(Y,`⚠️ ${Q}已处理,但原卡更新失败。${z}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await g2(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${z}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let H=Z?.toast,G=typeof H?.content==="string"&&H.content.trim()?H.content.trim():`${Q}已完成`,W=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||H?.type==="error"&&!W;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await g2(Y,`${K?"❌":"✅"} ${Q}: ${G}`)}async function NT($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await g2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${i6(J)}失败: ${Q}`)}function y_($){return RT.accept($)}async function TT($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="agent_project_cancel"){let X=await Q9.cancelProjectRunFromCard(String(J.run_id??""),Q,String($?.context?.open_message_id??""),Y);return W0({toast:{type:"success",content:X?"项目任务已停止":"项目任务已结束"}},!0)}if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let X=String(J.notify_id??""),z=j1(X);if(z)$.__cardActionChatId=z.chatId;if(J.kind==="notify_callback")return await ET(J,Q,Y);let H=J.kind==="notify_reply"?await d6.open(X,Q,Y):await d6.cancel(X,String(J.reply_id??""),Q,Y),G=W0({toast:{type:H.ok?"success":"error",content:H.message},__cardActionPresented:H.presented===!0},H.ok);return z?s$(z,G):G}let V=C$.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 z=await V.onPermissionDecision(J.request_id,X,Y);return W0({toast:{type:z.ok?X==="deny"?"error":"success":"error",content:z.message}},z.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(O$(g1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(z){let H=z instanceof Error?z.message:String(z);return W0(O$(g1({title:"\uD83D\uDCCB 菜单选择",message:H,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return t$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return t$(X)}case"model_list_open":{let X=String(J.panel_id??""),z=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return t$(await(J.mode==="add"?V.onModelAddOpen(X,z):V.onProviderSelect(z,X)))}case"model_add":case"model_remove":case"model_custom_remove":return t$(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 t$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return t$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return t$(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 t$(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 G=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",W=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,G,Y);return W0({toast:{type:W?"success":"error",content:W?"已回答":G.trim()?"问题已失效或答案未被接受":"请输入答案"}},W)}let z=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return W0({toast:{type:z?"success":"error",content:z?"已回答":"问题已失效或选项无效"}},z)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return W0(O$(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}}:O$(g1({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}}:O$(g1({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(O$(gQ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return W0(O$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return W0(O$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return W0(O$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (b7(),C7));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return t$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Y))}return{toast:{type:"info",content:"unknown action"}}}async function ET($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=j1(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(i4(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((G)=>G.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{k3(V.notifyId,X.id,J)}catch(G){return s$(V,W0({toast:{type:"error",content:`保存反馈结果失败: ${G instanceof Error?G.message:G}`}},!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,{...O$(u1(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}try{wK(V.notifyId,X.id,J)}catch(G){return s$(V,W0({toast:{type:"error",content:`保存回调发送状态失败,未发送: ${G instanceof Error?G.message:G}`}},!1))}S3(V.notifyId);let z=YV(xT(V,X,J));z.catch((G)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let H=z.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return s$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:H})}async function xT($,Z,J){try{let Q=u1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await E4($.messageId,Q)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${z instanceof Error?z.message:z}`)}let Y=await KY($,Z,J),V=Y.ok?"complete":"retry",X;if(Y.ok){let z=D6($.notifyId,Z.id,J);if(z.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:z.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${z.detail}`);try{await g2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${z.detail}`)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${H instanceof Error?H.message:H}`)}}}else{let z=vK($.notifyId);V=z.state,X={status:z.state==="retry"?"failed":"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:z.state==="retry"?Y.detail:`${Y.detail}; ${z.detail}`}}try{let z=u1($,X);await E4($.messageId,z)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${z instanceof Error?z.message:z}`);try{await g2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":V==="unknown"?"送达状态未知且结果卡更新失败,禁止自动重试":"已执行,但结果卡更新失败"}: ${z instanceof Error?z.message:z}`)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${H instanceof Error?H.message:H}`)}}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{C3($.notifyId)}}function JV($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function ST(){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(QV(o1))u6(o1)}catch{}try{Bun.serve({unix:o1,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(t0)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(!QV(i3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Y={};try{Y=JSON.parse(BT(i3,"utf8"))}catch(W){return new Response(`ctx read failed: ${W}`,{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 W=C$.get(Y.chat_id);return W?Response.json(pY(W)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let W=C$.get(Y.chat_id);if(!W)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():"",j=W.modelPanels.get(K);if(!j?.messageId||j.messageId!==Q.message_id)throw Error("stale or mismatched model panel");let _=await K0.im.v1.message.get({path:{message_id:Q.message_id}});if(_.code!==0)throw Error(`message.get failed: ${v(_)}`);let D=Wj(Q,Y,_.data?.items?.[0],m.feishu.app_id,j.messageId);B(`debug: model action ${Q.value.kind} chat=${Y.chat_id.slice(0,8)}…`);let L=y_(D);return await F1.enqueue(Y.chat_id,async()=>{}),Response.json({admission:L,state:pY(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(Q.text??"");if(!X)return new Response("text required",{status:400});let z=`【自动化测试】:${X}`,H=await k(Y.chat_id,z);if(!H)return new Response("sendText failed — see daemon log",{status:502});let G={sender:{sender_id:{open_id:Y.sender_open_id}},message:{message_id:H,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=${H}`),!w_(G,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Q.wait_for_handling===!0)await F1.enqueue(Y.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:H}),{headers:{"content-type":"application/json"}})}});try{WT(o1,384)}catch{}B(`debug: inject socket listening at ${o1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function CT(){B(`lodestar-daemon: pid ${process.pid} starting`),m2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (M7(),HG));if(t0)return;$();let{refreshAllTokenSourceModels:Z,listTokenSourceAccounts:J}=await Promise.resolve().then(() => (X0(),Qz));if(t0)return;if(await Z(),await Promise.allSettled(J().map(vz)),t0)return;if(HX(),R9.start(),mZ(),lZ(),uZ(),iZ(),oZ(),await p9(),t0)return;setInterval(()=>{p9()},1800000);let{reconcileTasklistDeletions:Q}=await Promise.resolve().then(() => (xY(),EY));if(t0)return;try{await Q()}catch(x){B(`tasklist deletion reconcile failed: ${x instanceof Error?x.message:x}`)}if(t0)return;let Y,V=Date.now(),X=0,z=!1,H=null,G=1500,W=90000,K=600000,j=3,_=null,D=0,L="",P=!1,F=(x)=>{B(`[ws] rebuild requested before WS init — ${x}`)},U=(x,p=0,n=!1)=>{if(t0)return;let z0=Date.now()+p;if(_){if(P||=n,z0>=D){B(`[ws] rebuild already scheduled — ${x}`);return}clearTimeout(_)}D=z0,L=x,P=n,_=setTimeout(()=>{let k$=L,p2=P;_=null,D=0,L="",P=!1,F(k$,p2)},p)},A={error:(x)=>B(`[ws-sdk error] ${JV(x)}`),warn:(x)=>{let p=JV(x);if(B(`[ws-sdk warn] ${p}`),p.includes("no pong/inbound"))U("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-V<K)},info:(x)=>B(`[ws-sdk] ${JV(x)}`),debug:(x)=>{},trace:(x)=>{}},M=new Y9.EventDispatcher({}),O=()=>{if(V=Date.now(),X=0,H)clearTimeout(H),H=null};M.register({"im.message.receive_v1":async(x)=>{if(O(),!w_(x))throw Error("daemon shutdown in progress")}}),M.register({"card.action.trigger":async(x)=>{return O(),y_(x)}});let R=()=>new Y9.WSClient({appId:m.feishu.app_id,appSecret:m.feishu.app_secret,loggerLevel:Y9.LoggerLevel.info,logger:A,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>T(),onError:(x)=>F(`SDK onError: ${x?.message??x}`)});F=(x,p=!1)=>{if(t0)return;if(z){B(`[ws] rebuild skipped (already rebuilding) — ${x}`);return}if(_)clearTimeout(_),_=null,D=0;z=!0,X++,B(`[ws] rebuild #${X} (fresh WSClient) — ${x}`);let n=Y;try{n?.close({force:!0})}catch(z0){B(`[ws] rebuild: old close failed: ${z0}`)}if(Y=R(),Y.start({eventDispatcher:M}).catch((z0)=>{B(`[ws] rebuild start failed: ${z0}`),U(`fresh client start failed: ${z0}`,G,p)}),z=!1,p)w()};let w=()=>{if(H)clearTimeout(H);let x=Date.now();H=setTimeout(()=>{if(H=null,V>=x){X=0;return}if(X>=j){B(`[ws] STILL deaf after ${j} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),X=0;return}F(`verify: no event ${Math.round((Date.now()-x)/1000)}s after rebuild`,!0)},W)},T=()=>{let x=Date.now()-V<K;B("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${x})`),X=0,U("post-reconnect precaution",G,x)};Y=R();let f=15000,u=2,C=0,g=setInterval(()=>{if(t0)return;let{state:x}=Y.getConnectionStatus();if(x==="connected"){C=0;return}if(x==="failed"||x==="idle"){C=0,F(`watchdog: state=${x}`);return}if(C++,B(`[ws] watchdog: state=${x} (${C}/${u})`),C>=u)C=0,F(`watchdog: stuck in '${x}' ~${Math.round(f*u/1000)}s`)},f);C_=()=>{if(clearInterval(g),_)clearTimeout(_);if(H)clearTimeout(H);Y.close({force:!0})};let Y0=bK(),e=V_(c4(m.notify.bind,m.notify.port));Pj({bind:m.notify.bind,port:m.notify.port,extraHandler:(x,p,n)=>W_(x,p,n,{service:Q9,authorizeProject:(z0,k$)=>X_(e,z0)?Q9.projectPrincipal(H_(k$)):null,authorizeSession:(z0)=>{for(let k$ of C$.values())if(k$.acceptsAgentCapability(z0))return k$;return null}})}),P_(),Nj(),gj(),h6("lodestar-files");let E=m2.enqueue();S_=rV(B,{enabled:m.runtime.agent_auto_update}),Y.start({eventDispatcher:M}).catch((x)=>{B(`[ws] initial start failed: ${x}`),U(`initial start failed: ${x}`,G,!1)}),B(`lodestar-daemon: WS start requested, watching ${L0.size} groups`),ST();for(let x of Y0)YV(F1.enqueue(x.chatId,()=>d6.recover(x))).catch((p)=>B(`notify-reply recovery failed: ${p instanceof Error?p.message:p}`));await E}var T_=!1,t0=!1,l6=null,i1=0,S_,C_,E_=15000,b_=()=>{if(T_)return;T_=!0;try{m2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{u6(K$)}catch{}try{u6(o1)}catch{}},C$,Q9,F1,m2,PT,k_,LT,VV,MT=30000,J9,d6,RT;var f_=N(()=>{N5();QZ();l8();gJ();NY();$0();M$();Kj();w3();y6();y6();Rj();Ej();Y_();z_();G_();GJ();x7();K_();uY();I6();L_();f0();h();Z4();H0();H5();qZ();R_();{let $=a3(K$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(QV(K$))try{u6(K$)}catch{}}KT(_T(K$),{recursive:!0});UV(K$);process.on("exit",b_);process.on("SIGTERM",()=>{V9("SIGTERM",0)});process.on("SIGINT",()=>{V9("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{V9("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),V9("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),V9("uncaughtException",1)});C$=new Map,Q9=new oY,F1=new y9,m2=new ZV({readMarker:eZ,writeMarker:rZ,sessions:()=>C$.values(),chatIdForSession:Z7,sessionFor:v_,actor:F1,isShuttingDown:()=>t0,log:B}),PT=new LZ(30000),k_=new Set,LT=yz({actor:F1,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>OT($,Z)});VV=N_({registry:C$,createSession:($,Z)=>{let J=new S$($,Z,{agentCards:Q9.presentation,onLifecycleChange:qT,onCreateTempSession:DT,onDisbandTempSession:FT,onCancelAgentRuns:(Q,Y,V)=>Q9.cancelSessionRuns(Q,Y,V)});return m2.transferPending(J),J},ensureChatForSession:ZJ,disbandChatForSessionExact:QJ,chatIdForSession:Z7,clearSessionConversationState:tZ,registerTempSessionLease:pZ,hasTempSessionLease:cZ,replaceTurnAnchors:V$,runExclusive:($,Z)=>F1.enqueue($,Z),log:B});J9=new Set,d6=Tj({sendCard:i,updateCard:E4,sendText:k,dispatch:KY,onWaitingChanged:($)=>C$.get($)?.refreshPendingAsks(),log:B});RT=fz({actor:F1,deduper:PT,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=j1(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(t0)C$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return TT($)},present:x_,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await NT($,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??""),`⚠️ ${i6(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__modelActionCompletion;if(J)return MX(J,(Y)=>x_($,t$(Y)));let Q=Z?.__cardActionCompletion;return Q&&typeof Q.then==="function"?Q:null},track:($)=>{YV($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${i6(String($?.action?.value?.kind??"unknown"))}已接收,后台处理中…`}}),inflight:()=>({toast:{type:"info",content:"相同操作正在处理…"}}),completed:()=>({toast:{type:"info",content:"该操作近期已执行或尝试;为防重复暂不再次执行,请查看原卡或群消息"}}),closed:()=>({toast:{type:"error",content:"服务正在重启,请稍后重试"}}),invalid:($,Z)=>({toast:{type:"error",content:Z}})}});CT().catch(($)=>{B(`boot fatal: ${$}`),V9("boot fatal",1)})});H0();H5();import{existsSync as h_,unlinkSync as kT}from"node:fs";var b$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function wT(){if(!h_(v0)){if(process.stdin.isTTY){console.log(),console.log(`${b$.bold}${b$.yellow}Lodestar: 未找到配置, 启动安装向导...${b$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (zX(),XX));await Z();return}console.error(`${b$.red}Lodestar: 未找到配置 ${v0}${b$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${b$.green}lodestar-setup${b$.reset} 完成首次配置 (或直接运行 ${b$.green}lodestar-daemon${b$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=a3(K$);if($.state==="exit")console.error(`${b$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${b$.reset}`),console.error(" • 想看日志:"+(process.platform==="win32"?" %LOCALAPPDATA%\\Lodestar\\daemon-YYYY-MM-DD.log":" ~/.local/share/lodestar/daemon-YYYY-MM-DD.log")),console.error(" • 想停: 任务管理器结束 pid 上面那个号 (Windows) / `kill "+$.pid+"` (Linux/macOS)"),console.error(` • 误判 / 已经死了: 手删 ${K$} 后再跑`),process.exit(1);if(h_(K$))kT(K$);await Promise.resolve().then(() => (f_(),bT))}wT().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
593
+ `),imageKeys:Z,fileKeys:J}}async function fT($,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&&J9.has(V))return;if(V){if(J9.add(V),J9.size>200){let A=[...J9];J9.clear();for(let M of A.slice(-100))J9.add(M)}}let X=Number(J.create_time??0);if(N_(X,Z,yT)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)X$(V,"CrossMark");return}let z=J.chat_id,H={};try{H=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?H.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{ET(n3,JSON.stringify({chat_id:z,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${z.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(M){B(`debug: seed context failed: ${M}`)}let A=G.slice(7);H.text=A,J.content=JSON.stringify(H)}let W=P0.get(z);if(!W)await c9(),W=P0.get(z);if(!W)W=await VJ(z)??void 0;if(!W){B(`unknown chat ${z}, dropping message`),await b(z,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=GJ(W);M4(K,z);let j=p_(z,K),_={};try{_=JSON.parse(J.content??"{}")}catch{}let D=J.message_type,P="",L=!1,F=[];if(D==="text")P=(_.text??"").trim();else if(D==="post"){let A=vT(_);L=A.imageKeys.length>0||A.fileKeys.length>0,P=A.markdown.trim();for(let M of A.imageKeys){let O=await l9(J.message_id,M,"image");if(O)F.push(O)}for(let M of A.fileKeys){let O=await l9(J.message_id,M.key,"file",M.name);if(O)F.push(O)}}if(D==="text"&&P){if(await j.runCommand(P,Y,V))return}if((D==="text"||D==="post")&&P&&!L&&await R_({reply:()=>i6.consume({chatId:z,openId:Y,messageId:V??"",text:P,createTime:X,parentId:J.parent_id}),hasQuestion:()=>j.hasPendingAsk(),answerQuestion:()=>j.onAskMessageAnswer(P,Y,V??"")}))return;if(D==="text"&&P&&await j.consumeModelCustomMessage(P,Y))return;let U=E_(D,_);if(U){let A=await l9(J.message_id,U.key,U.type,U.name);if(!A){await b(z,T_(D));return}if(F.push(A),!P&&U.displayText)P=U.displayText}if(!P&&F.length===0){B(`drop empty message ${V} type=${D}`);return}if(await j.onMultiMessageInbound(P,F,Y,V??""))return;await j.onUserMessage(P||"(empty)",F,Y,V??"")}function n6($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复",agent_project_cancel:"停止项目任务"}[$]??$}function hT($){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 t$($){let Z=W0($.card?O$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok,$.pending?void 0:$.message);if($.completion)Z.__modelActionCompletion=$.completion;return Z}async function p2($,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 y_($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Q=n6(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=hT(Z),z=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await E4(V,X);return}catch(_){B(`card-action: ${J} original-card update failed: ${_ instanceof Error?_.message:_}`),await p2(Y,`⚠️ ${Q}已处理,但原卡更新失败。${z}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await p2(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${z}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let H=Z?.toast,G=typeof H?.content==="string"&&H.content.trim()?H.content.trim():`${Q}已完成`,W=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||H?.type==="error"&&!W;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await p2(Y,`${K?"❌":"✅"} ${Q}: ${G}`)}async function IT($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await p2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${n6(J)}失败: ${Q}`)}function c_($){return gT.accept($)}async function mT($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="agent_project_cancel"){let X=await Q9.cancelProjectRunFromCard(String(J.run_id??""),Q,String($?.context?.open_message_id??""),Y);return W0({toast:{type:"success",content:X?"项目任务已停止":"项目任务已结束"}},!0)}if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let X=String(J.notify_id??""),z=j1(X);if(z)$.__cardActionChatId=z.chatId;if(J.kind==="notify_callback")return await pT(J,Q,Y);let H=J.kind==="notify_reply"?await i6.open(X,Q,Y):await i6.cancel(X,String(J.reply_id??""),Q,Y),G=W0({toast:{type:H.ok?"success":"error",content:H.message},__cardActionPresented:H.presented===!0},H.ok);return z?s$(z,G):G}let V=C$.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 z=await V.onPermissionDecision(J.request_id,X,Y);return W0({toast:{type:z.ok?X==="deny"?"error":"success":"error",content:z.message}},z.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(O$(g1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(z){let H=z instanceof Error?z.message:String(z);return W0(O$(g1({title:"\uD83D\uDCCB 菜单选择",message:H,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return t$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return t$(X)}case"model_list_open":{let X=String(J.panel_id??""),z=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return t$(await(J.mode==="add"?V.onModelAddOpen(X,z):V.onProviderSelect(z,X)))}case"model_add":case"model_remove":case"model_custom_remove":return t$(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 t$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return t$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return t$(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 t$(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 G=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",W=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,G,Y);return W0({toast:{type:W?"success":"error",content:W?"已回答":G.trim()?"问题已失效或答案未被接受":"请输入答案"}},W)}let z=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return W0({toast:{type:z?"success":"error",content:z?"已回答":"问题已失效或选项无效"}},z)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return W0(O$(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}}:O$(g1({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}}:O$(g1({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(O$(mQ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return W0(O$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return W0(O$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return W0(O$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (k7(),b7));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return t$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Y))}return{toast:{type:"info",content:"unknown action"}}}async function pT($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=j1(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(i4(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((G)=>G.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{w3(V.notifyId,X.id,J)}catch(G){return s$(V,W0({toast:{type:"error",content:`保存反馈结果失败: ${G instanceof Error?G.message:G}`}},!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,{...O$(u1(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}try{mK(V.notifyId,X.id,J)}catch(G){return s$(V,W0({toast:{type:"error",content:`保存回调发送状态失败,未发送: ${G instanceof Error?G.message:G}`}},!1))}C3(V.notifyId);let z=VV(cT(V,X,J));z.catch((G)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let H=z.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return s$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:H})}async function cT($,Z,J){try{let Q=u1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await E4($.messageId,Q)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${z instanceof Error?z.message:z}`)}let Y=await BY($,Z,J),V=Y.ok?"complete":"retry",X;if(Y.ok){let z=F6($.notifyId,Z.id,J);if(z.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:z.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${z.detail}`);try{await p2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${z.detail}`)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${H instanceof Error?H.message:H}`)}}}else{let z=pK($.notifyId);V=z.state,X={status:z.state==="retry"?"failed":"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:z.state==="retry"?Y.detail:`${Y.detail}; ${z.detail}`}}try{let z=u1($,X);await E4($.messageId,z)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${z instanceof Error?z.message:z}`);try{await p2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":V==="unknown"?"送达状态未知且结果卡更新失败,禁止自动重试":"已执行,但结果卡更新失败"}: ${z instanceof Error?z.message:z}`)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${H instanceof Error?H.message:H}`)}}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{b3($.notifyId)}}function QV($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function lT(){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(YV(s1))d6(s1)}catch{}try{Bun.serve({unix:s1,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(t0)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(!YV(n3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Y={};try{Y=JSON.parse(TT(n3,"utf8"))}catch(W){return new Response(`ctx read failed: ${W}`,{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 W=C$.get(Y.chat_id);return W?Response.json(cY(W)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let W=C$.get(Y.chat_id);if(!W)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():"",j=W.modelPanels.get(K);if(!j?.messageId||j.messageId!==Q.message_id)throw Error("stale or mismatched model panel");let _=await K0.im.v1.message.get({path:{message_id:Q.message_id}});if(_.code!==0)throw Error(`message.get failed: ${w(_)}`);let D=qj(Q,Y,_.data?.items?.[0],m.feishu.app_id,j.messageId);B(`debug: model action ${Q.value.kind} chat=${Y.chat_id.slice(0,8)}…`);let P=c_(D);return await F1.enqueue(Y.chat_id,async()=>{}),Response.json({admission:P,state:cY(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(Q.text??"");if(!X)return new Response("text required",{status:400});let z=`【自动化测试】:${X}`,H=await b(Y.chat_id,z);if(!H)return new Response("sendText failed — see daemon log",{status:502});let G={sender:{sender_id:{open_id:Y.sender_open_id}},message:{message_id:H,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=${H}`),!m_(G,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Q.wait_for_handling===!0)await F1.enqueue(Y.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:H}),{headers:{"content-type":"application/json"}})}});try{NT(s1,384)}catch{}B(`debug: inject socket listening at ${s1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function uT(){B(`lodestar-daemon: pid ${process.pid} starting`),c2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (O7(),LG));if(t0)return;$();let{refreshAllTokenSourceModels:Z,listTokenSourceAccounts:J}=await Promise.resolve().then(() => (z0(),Wz));if(t0)return;if(await Z(),await Promise.allSettled(J().map(pz)),t0)return;if(WX(),T9.start(),pZ(),uZ(),dZ(),nZ(),sZ(),await c9(),t0)return;setInterval(()=>{c9()},1800000);let{reconcileTasklistDeletions:Q}=await Promise.resolve().then(() => (SY(),xY));if(t0)return;try{await Q()}catch(N){B(`tasklist deletion reconcile failed: ${N instanceof Error?N.message:N}`)}if(t0)return;let Y,V=Date.now(),X=0,z=!1,H=null,G=1500,W=90000,K=600000,j=3,_=null,D=0,P="",L=!1,F=(N)=>{B(`[ws] rebuild requested before WS init — ${N}`)},U=(N,y=0,p=!1)=>{if(t0)return;let J0=Date.now()+y;if(_){if(L||=p,J0>=D){B(`[ws] rebuild already scheduled — ${N}`);return}clearTimeout(_)}D=J0,P=N,L=p,_=setTimeout(()=>{let k$=P,n1=L;_=null,D=0,P="",L=!1,F(k$,n1)},y)},A={error:(N)=>B(`[ws-sdk error] ${QV(N)}`),warn:(N)=>{let y=QV(N);if(B(`[ws-sdk warn] ${y}`),y.includes("no pong/inbound"))U("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-V<K)},info:(N)=>B(`[ws-sdk] ${QV(N)}`),debug:(N)=>{},trace:(N)=>{}},M=new Y9.EventDispatcher({}),O=()=>{if(V=Date.now(),X=0,H)clearTimeout(H),H=null};M.register({"im.message.receive_v1":async(N)=>{if(O(),!m_(N))throw Error("daemon shutdown in progress")}}),M.register({"card.action.trigger":async(N)=>{return O(),c_(N)}});let T=()=>new Y9.WSClient({appId:m.feishu.app_id,appSecret:m.feishu.app_secret,loggerLevel:Y9.LoggerLevel.info,logger:A,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>E(),onError:(N)=>F(`SDK onError: ${N?.message??N}`)});F=(N,y=!1)=>{if(t0)return;if(z){B(`[ws] rebuild skipped (already rebuilding) — ${N}`);return}if(_)clearTimeout(_),_=null,D=0;z=!0,X++,B(`[ws] rebuild #${X} (fresh WSClient) — ${N}`);let p=Y;try{p?.close({force:!0})}catch(J0){B(`[ws] rebuild: old close failed: ${J0}`)}if(Y=T(),Y.start({eventDispatcher:M}).catch((J0)=>{B(`[ws] rebuild start failed: ${J0}`),U(`fresh client start failed: ${J0}`,G,y)}),z=!1,y)k()};let k=()=>{if(H)clearTimeout(H);let N=Date.now();H=setTimeout(()=>{if(H=null,V>=N){X=0;return}if(X>=j){B(`[ws] STILL deaf after ${j} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),X=0;return}F(`verify: no event ${Math.round((Date.now()-N)/1000)}s after rebuild`,!0)},W)},E=()=>{let N=Date.now()-V<K;B("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${N})`),X=0,U("post-reconnect precaution",G,N)};Y=T();let f=15000,d=2,S=0,g=setInterval(()=>{if(t0)return;let{state:N}=Y.getConnectionStatus();if(N==="connected"){S=0;return}if(N==="failed"||N==="idle"){S=0,F(`watchdog: state=${N}`);return}if(S++,B(`[ws] watchdog: state=${N} (${S}/${d})`),S>=d)S=0,F(`watchdog: stuck in '${N}' ~${Math.round(f*d/1000)}s`)},f);h_=()=>{if(clearInterval(g),_)clearTimeout(_);if(H)clearTimeout(H);Y.close({force:!0})};let V0=IK(),e=B_(c4(m.notify.bind,m.notify.port));Oj({bind:m.notify.bind,port:m.notify.port,extraHandler:(N,y,p)=>q_(N,y,p,{service:Q9,authorizeProject:(J0,k$)=>j_(e,J0)?Q9.projectPrincipal(L_(k$)):null,authorizeSession:(J0)=>{for(let k$ of C$.values())if(k$.acceptsAgentCapability(J0))return k$;return null}})}),O_(),bj(),ij(),I6("lodestar-files");let c=c2.enqueue();f_=$X(B,{enabled:m.runtime.agent_auto_update}),Y.start({eventDispatcher:M}).catch((N)=>{B(`[ws] initial start failed: ${N}`),U(`initial start failed: ${N}`,G,!1)}),B(`lodestar-daemon: WS start requested, watching ${P0.size} groups`),lT();for(let N of V0)VV(F1.enqueue(N.chatId,()=>i6.recover(N))).catch((y)=>B(`notify-reply recovery failed: ${y instanceof Error?y.message:y}`));await c}var w_=!1,t0=!1,u6=null,i1=0,f_,h_,v_=15000,I_=()=>{if(w_)return;w_=!0;try{c2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{d6(K$)}catch{}try{d6(s1)}catch{}},C$,Q9,F1,c2,ST,g_,CT,XV,yT=30000,J9,i6,gT;var l_=R(()=>{R5();YZ();u8();mJ();RY();$0();M$();Dj();v3();f6();f6();kj();vj();K_();__();P_();WJ();S7();D_();dY();g6();A_();f0();h();Z4();H0();G5();DZ();k_();{let $=o3(K$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(YV(K$))try{d6(K$)}catch{}}RT(xT(K$),{recursive:!0});OV(K$);process.on("exit",I_);process.on("SIGTERM",()=>{V9("SIGTERM",0)});process.on("SIGINT",()=>{V9("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{V9("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),V9("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),V9("uncaughtException",1)});C$=new Map,Q9=new sY,F1=new f9,c2=new JV({readMarker:$J,writeMarker:eZ,sessions:()=>C$.values(),chatIdForSession:J7,sessionFor:p_,actor:F1,isShuttingDown:()=>t0,log:B}),ST=new qZ(30000),g_=new Set,CT=cz({actor:F1,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>fT($,Z)});XV=b_({registry:C$,createSession:($,Z)=>{let J=new S$($,Z,{agentCards:Q9.presentation,onLifecycleChange:bT,onCreateTempSession:kT,onDisbandTempSession:wT,onCancelAgentRuns:(Q,Y,V)=>Q9.cancelSessionRuns(Q,Y,V)});return c2.transferPending(J),J},ensureChatForSession:JJ,disbandChatForSessionExact:YJ,chatIdForSession:J7,clearSessionConversationState:rZ,registerTempSessionLease:cZ,hasTempSessionLease:lZ,replaceTurnAnchors:V$,runExclusive:($,Z)=>F1.enqueue($,Z),log:B});J9=new Set,i6=wj({sendCard:n,updateCard:E4,sendText:b,dispatch:BY,onWaitingChanged:($)=>C$.get($)?.refreshPendingAsks(),log:B});gT=lz({actor:F1,deduper:ST,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=j1(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(t0)C$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return mT($)},present:y_,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await IT($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await p2(String($?.context?.open_chat_id??""),`⚠️ ${n6(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__modelActionCompletion;if(J)return xX(J,(Y)=>y_($,t$(Y)));let Q=Z?.__cardActionCompletion;return Q&&typeof Q.then==="function"?Q:null},track:($)=>{VV($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${n6(String($?.action?.value?.kind??"unknown"))}已接收,后台处理中…`}}),inflight:()=>({toast:{type:"info",content:"相同操作正在处理…"}}),completed:()=>({toast:{type:"info",content:"该操作近期已执行或尝试;为防重复暂不再次执行,请查看原卡或群消息"}}),closed:()=>({toast:{type:"error",content:"服务正在重启,请稍后重试"}}),invalid:($,Z)=>({toast:{type:"error",content:Z}})}});uT().catch(($)=>{B(`boot fatal: ${$}`),V9("boot fatal",1)})});H0();G5();import{existsSync as u_,unlinkSync as iT}from"node:fs";var b$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function nT(){if(!u_(v0)){if(process.stdin.isTTY){console.log(),console.log(`${b$.bold}${b$.yellow}Lodestar: 未找到配置, 启动安装向导...${b$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (GX(),HX));await Z();return}console.error(`${b$.red}Lodestar: 未找到配置 ${v0}${b$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${b$.green}lodestar-setup${b$.reset} 完成首次配置 (或直接运行 ${b$.green}lodestar-daemon${b$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=o3(K$);if($.state==="exit")console.error(`${b$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${b$.reset}`),console.error(" • 想看日志:"+(process.platform==="win32"?" %LOCALAPPDATA%\\Lodestar\\daemon-YYYY-MM-DD.log":" ~/.local/share/lodestar/daemon-YYYY-MM-DD.log")),console.error(" • 想停: 任务管理器结束 pid 上面那个号 (Windows) / `kill "+$.pid+"` (Linux/macOS)"),console.error(` • 误判 / 已经死了: 手删 ${K$} 后再跑`),process.exit(1);if(u_(K$))iT(K$);await Promise.resolve().then(() => (l_(),dT))}nT().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});