@leviyuan/lodestar 0.19.3 → 0.19.4

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.
Files changed (2) hide show
  1. package/dist/lodestar.js +116 -116
  2. package/package.json +1 -1
package/dist/lodestar.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as Yj}from"node:module";var o_=Object.create;var{getPrototypeOf:s_,defineProperty:C7,getOwnPropertyNames:t_}=Object;var r_=Object.prototype.hasOwnProperty;function e_($){return this[$]}var $j,Zj,hY=($,Z,J)=>{var Q=$!=null&&typeof $==="object";if(Q){var Y=Z?$j??=new WeakMap:Zj??=new WeakMap,V=Y.get($);if(V)return V}J=$!=null?o_(s_($)):{};let X=Z||!$||!$.__esModule?C7(J,"default",{value:$,enumerable:!0}):J;for(let H of t_($))if(!r_.call(X,H))C7(X,H,{get:e_.bind($,H),enumerable:!0});if(Q)Y.set($,X);return X};var IY=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var Jj=($)=>$;function Qj($,Z){this[$]=Jj.bind(null,Z)}var d$=($,Z)=>{for(var J in Z)C7($,J,{get:Z[J],enumerable:!0,configurable:!0,set:Qj.bind(Z,J)})};var R=($,Z)=>()=>($&&(Z=$($=0)),Z);var R2=Yj(import.meta.url);var b7=IY((bR,pY)=>{var{homedir:gY}=R2("node:os"),{join:l4}=R2("node:path");function mY(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return l4(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return l4(process.env.LOCALAPPDATA??l4(gY(),"AppData","Local"),"Lodestar");return l4(gY(),".local","share","lodestar")}function Vj(){return l4(mY(),"managed-claude-plugin")}pY.exports={lodestarDataDir:mY,managedClaudePluginDir:Vj}});import{homedir as Xj}from"node:os";import{join as t}from"node:path";function zj($,Z,J){if($)return $;if(Z)return t(Z,"lodestar");return J}function Gj(){if(Hj)return t(process.env.APPDATA??t(cY,"AppData","Roaming"),"Lodestar");return t(cY,".config","lodestar")}var R3,cY,Hj,k7,r,w0,H$,T2,w7,y7,v7,f7,h7,T3,g1,x3,x2,E2,lY,uY,dY,I7,iY,nY,g7,m7,aY,p7,m1,E3;var V0=R(()=>{R3=hY(b7(),1),cY=Xj(),Hj=process.platform==="win32";k7=zj(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,Gj()),r=R3.lodestarDataDir(),w0=process.env.LODESTAR_CONFIG??t(k7,"config.toml"),H$=t(r,"daemon.pid"),T2=t(r,"daemon.log"),w7=t(r,"session-chat-map.json"),y7=t(r,"session-resume-map.json"),v7=t(r,"session-turns-map.json"),f7=t(r,"session-model-map.json"),h7=t(r,"temp-session-leases.json"),T3=t(r,"tasklist-map.json"),g1=t(r,"agent-runs"),x3=t(r,"agent-session-ids.json"),x2=R3.managedClaudePluginDir(),E2=t(r,"dsh"),lY=t(r,"codex-accounts"),uY=t(r,"codex-accounts.json"),dY=t(r,"codex-quota-blocks.json"),I7=t(r,"agent-runtimes"),iY=t(r,"context-window-cache.json"),nY=t(r,"notify-callbacks.json"),g7=t(r,"alive-on-shutdown.json"),m7=t(r,"inbox"),aY=t(r,"file-deliveries"),p7=t(r,"file-delivery-groups.json"),m1=t(r,"debug.sock"),E3=t(r,"debug-context.json")});import{execFileSync as l7}from"node:child_process";import{readFileSync as oY,readlinkSync as Wj,writeFileSync as Kj}from"node:fs";import{isAbsolute as Bj,resolve as S3,win32 as c7}from"node:path";function _j(){if(!process.argv[1])throw Error("无法确定 daemon 入口路径");return S3(process.argv[1])}function jj($){if(!/^[1-9]\d*$/.test($.trim()))return null;let Z=Number($.trim());return Number.isSafeInteger(Z)&&Z<=2147483647?Z:null}function u7($){try{return process.kill($,0),!0}catch(Z){if(Z.code==="ESRCH")return!1;throw Z}}function qj($){if(!u7($))return null;try{let Z;if(process.platform==="linux")Z=oY(`/proc/${$}/cmdline`,"utf8");else if(process.platform==="darwin")Z=l7("ps",["-p",String($),"-o","args="],{encoding:"utf8",timeout:2000});else if(process.platform==="win32")Z=l7("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(!u7($))return null;throw Error(`无法读取 PID ${$} 的命令行: ${Z instanceof Error?Z.message:String(Z)}`,{cause:Z})}}function Uj($){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?Dj:Lj,Y=J?Fj:Pj,V=!1,X=1;while(X<$.length){let H=$[X];if(/^-[ep]/.test(H)||H==="--eval"||H==="--print"||/^(?:--eval|--print)=/.test(H))return null;if(!J&&(H==="-c"||H==="--check"||H==="--run"||H.startsWith("--run=")))return null;if(H==="--")return X+1;if(!H.startsWith("-")){if(J&&!V&&H==="run"){V=!0,X++;continue}return X}let z=H.split("=")[0];if(Q.has(z))X+=H.includes("=")?1:2;else if(Y.has(z))X++;else throw Error(`无法安全核对 daemon 入口: 未识别的 ${Z} 选项 ${H}`)}return null}function Mj($){if(process.platform==="linux")return Wj(`/proc/${$}/cwd`);if(process.platform==="darwin"){let J=l7("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 Oj($,Z){if(!Number.isSafeInteger($)||$<=0||$>2147483647||!Z)return!1;let J=qj($);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=Uj(Q);if(Y===null||!Q[Y])return!1;let V=Q[Y];if(process.platform==="win32"){if(!c7.isAbsolute(V))throw Error(`PID ${$} 使用相对入口,无法安全核对 daemon 身份`);return c7.normalize(V).toLowerCase()===c7.normalize(Z).toLowerCase()}if(process.platform==="darwin"&&Z.startsWith(`${V} `))throw Error(`PID ${$} 的入口包含无法区分的空格,不能安全核对 daemon 身份`);if(!Bj(V))V=S3(Mj($),V);return S3(V)===S3(Z)}function C3($){let Z;try{Z=oY($,"utf8")}catch(V){if(V.code==="ENOENT")return{state:"continue"};throw V}let J=Z.split(`
2
+ import{createRequire as Yj}from"node:module";var o_=Object.create;var{getPrototypeOf:s_,defineProperty:C7,getOwnPropertyNames:t_}=Object;var r_=Object.prototype.hasOwnProperty;function e_($){return this[$]}var $j,Zj,hY=($,Z,J)=>{var Q=$!=null&&typeof $==="object";if(Q){var Y=Z?$j??=new WeakMap:Zj??=new WeakMap,V=Y.get($);if(V)return V}J=$!=null?o_(s_($)):{};let X=Z||!$||!$.__esModule?C7(J,"default",{value:$,enumerable:!0}):J;for(let H of t_($))if(!r_.call(X,H))C7(X,H,{get:e_.bind($,H),enumerable:!0});if(Q)Y.set($,X);return X};var IY=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var Jj=($)=>$;function Qj($,Z){this[$]=Jj.bind(null,Z)}var d$=($,Z)=>{for(var J in Z)C7($,J,{get:Z[J],enumerable:!0,configurable:!0,set:Qj.bind(Z,J)})};var R=($,Z)=>()=>($&&(Z=$($=0)),Z);var R2=Yj(import.meta.url);var b7=IY((bR,pY)=>{var{homedir:gY}=R2("node:os"),{join:l4}=R2("node:path");function mY(){if(process.env.LODESTAR_DATA_DIR)return process.env.LODESTAR_DATA_DIR;if(process.env.XDG_DATA_HOME)return l4(process.env.XDG_DATA_HOME,"lodestar");if(process.platform==="win32")return l4(process.env.LOCALAPPDATA??l4(gY(),"AppData","Local"),"Lodestar");return l4(gY(),".local","share","lodestar")}function Vj(){return l4(mY(),"managed-claude-plugin")}pY.exports={lodestarDataDir:mY,managedClaudePluginDir:Vj}});import{homedir as Xj}from"node:os";import{join as t}from"node:path";function zj($,Z,J){if($)return $;if(Z)return t(Z,"lodestar");return J}function Gj(){if(Hj)return t(process.env.APPDATA??t(cY,"AppData","Roaming"),"Lodestar");return t(cY,".config","lodestar")}var R3,cY,Hj,k7,r,w0,H$,T2,w7,y7,v7,f7,h7,T3,g1,x3,x2,E2,lY,uY,dY,I7,iY,nY,g7,m7,aY,p7,m1,E3;var V0=R(()=>{R3=hY(b7(),1),cY=Xj(),Hj=process.platform==="win32";k7=zj(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,Gj()),r=R3.lodestarDataDir(),w0=process.env.LODESTAR_CONFIG??t(k7,"config.toml"),H$=t(r,"daemon.pid"),T2=t(r,"daemon.log"),w7=t(r,"session-chat-map.json"),y7=t(r,"session-resume-map.json"),v7=t(r,"session-turns-map.json"),f7=t(r,"session-model-map.json"),h7=t(r,"temp-session-leases.json"),T3=t(r,"tasklist-map.json"),g1=t(r,"agent-runs"),x3=t(r,"agent-session-ids.json"),x2=R3.managedClaudePluginDir(),E2=t(r,"dsh"),lY=t(r,"codex-accounts"),uY=t(r,"codex-accounts.json"),dY=t(r,"codex-quota-blocks.json"),I7=t(r,"agent-runtimes"),iY=t(r,"context-window-cache.json"),nY=t(r,"notify-callbacks.json"),g7=t(r,"alive-on-shutdown.json"),m7=t(r,"inbox"),aY=t(r,"file-deliveries"),p7=t(r,"file-delivery-groups.json"),m1=t(r,"debug.sock"),E3=t(r,"debug-context.json")});import{execFileSync as l7}from"node:child_process";import{readFileSync as oY,readlinkSync as Wj,writeFileSync as Kj}from"node:fs";import{isAbsolute as Bj,resolve as S3,win32 as c7}from"node:path";function _j(){if(!process.argv[1])throw Error("无法确定 daemon 入口路径");return S3(process.argv[1])}function jj($){if(!/^[1-9]\d*$/.test($.trim()))return null;let Z=Number($.trim());return Number.isSafeInteger(Z)&&Z<=2147483647?Z:null}function u7($){try{return process.kill($,0),!0}catch(Z){if(Z.code==="ESRCH")return!1;throw Z}}function qj($){if(!u7($))return null;try{let Z;if(process.platform==="linux")Z=oY(`/proc/${$}/cmdline`,"utf8");else if(process.platform==="darwin")Z=l7("ps",["-p",String($),"-o","args="],{encoding:"utf8",timeout:2000});else if(process.platform==="win32")Z=l7("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(!u7($))return null;throw Error(`无法读取 PID ${$} 的命令行: ${Z instanceof Error?Z.message:String(Z)}`,{cause:Z})}}function Mj($){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?Dj:Lj,Y=J?Fj:Pj,V=!1,X=1;while(X<$.length){let H=$[X];if(/^-[ep]/.test(H)||H==="--eval"||H==="--print"||/^(?:--eval|--print)=/.test(H))return null;if(!J&&(H==="-c"||H==="--check"||H==="--run"||H.startsWith("--run=")))return null;if(H==="--")return X+1;if(!H.startsWith("-")){if(J&&!V&&H==="run"){V=!0,X++;continue}return X}let z=H.split("=")[0];if(Q.has(z))X+=H.includes("=")?1:2;else if(Y.has(z))X++;else throw Error(`无法安全核对 daemon 入口: 未识别的 ${Z} 选项 ${H}`)}return null}function Uj($){if(process.platform==="linux")return Wj(`/proc/${$}/cwd`);if(process.platform==="darwin"){let J=l7("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 Oj($,Z){if(!Number.isSafeInteger($)||$<=0||$>2147483647||!Z)return!1;let J=qj($);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=Mj(Q);if(Y===null||!Q[Y])return!1;let V=Q[Y];if(process.platform==="win32"){if(!c7.isAbsolute(V))throw Error(`PID ${$} 使用相对入口,无法安全核对 daemon 身份`);return c7.normalize(V).toLowerCase()===c7.normalize(Z).toLowerCase()}if(process.platform==="darwin"&&Z.startsWith(`${V} `))throw Error(`PID ${$} 的入口包含无法区分的空格,不能安全核对 daemon 身份`);if(!Bj(V))V=S3(Uj($),V);return S3(V)===S3(Z)}function C3($){let Z;try{Z=oY($,"utf8")}catch(V){if(V.code==="ENOENT")return{state:"continue"};throw V}let J=Z.split(`
4
4
  `),Q=jj(J[0]??""),Y=(J[1]??"").trim();if(Q===null)throw Error(`PID 文件格式坏: ${$}`);if(!Y)return u7(Q)?{state:"exit",pid:Q}:{state:"continue"};return Oj(Q,Y)?{state:"exit",pid:Q}:{state:"continue"}}function sY($){Kj($,`${process.pid}
5
5
  ${_j()}`)}var Lj,Pj,Dj,Fj;var d7=R(()=>{Lj=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"]),Pj=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"]),Dj=new Set(["--preload","--cwd","--config","-c","--env-file","--tsconfig-override"]),Fj=new Set(["--hot","--watch","--smol","--no-clear-screen","--silent","--bun","--no-install"])});import{execFile as Aj}from"node:child_process";import{readFile as Nj}from"node:fs/promises";import{homedir as Rj}from"node:os";import{join as tY}from"node:path";import{promisify as Tj}from"node:util";import{Address4 as b3,Address6 as k3}from"ip-address";function S2($,Z){return $[Z.toLowerCase()]?.trim()||$[Z]?.trim()||void 0}function f3($){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 i7($,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(b3.isValid(V))return b3.isValid(J)&&new b3(J).isInSubnet(new b3(V));if(k3.isValid(V))return k3.isValid(J)&&new k3(J).isInSubnet(new k3(V));throw Error("network proxy: invalid IP range in bypass list")}let X=V.match(/^(\[[^\]]+\]|[^:]+):(\d+)$/);if(X&&X[2]!==Q)return!1;let H=(X?X[1]:V).replace(/^\[|\]$/g,"").replace(/^\*?\./,"");return J===H||J.endsWith(`.${H}`)})}function rY($,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 eY($,Z,J={}){if(!["http:","https:"].includes($.protocol))throw Error(`network: unsupported URL protocol ${$.protocol}`);if(f3($)||i7($,S2(Z,"NO_PROXY")))return;let Q=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY",Y=S2(Z,Q)||S2(Z,"ALL_PROXY");if(Y)return rY(Y,"environment");if(J.unsupported)throw Error(`network proxy: ${J.unsupported}`);if(i7($,J.bypass))return;let V=($.protocol==="https:"?J.https:J.http)||J.all;return V?rY(V,"system settings"):void 0}function v3($,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 Ej($){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 Sj($){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=v3(Z("HTTPProxy"),Z("HTTPPort"));if(Z("HTTPSEnable")==="1")J.https=v3(Z("HTTPSProxy"),Z("HTTPSPort"));if(Z("SOCKSEnable")==="1")J.all=v3(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 w3($){if($===void 0)return"";if(!/^(['"]).*\1$/.test($))throw Error("network proxy: invalid GNOME proxy string");return $.slice(1,-1).replace(/\\([\\'"])/g,"$1")}function Cj($){let Z=new Map($.split(`
6
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=w3(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=w3(Z.get(`.${Y}/host`));if(!V)continue;let X=new URL(v3(V,Z.get(`.${Y}/port`),Y==="socks"?"socks":"http"));if(Y==="http"&&Z.get(".http/use-authentication")==="true")X.username=w3(Z.get(".http/authentication-user")),X.password=w3(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 bj($){let Z=$.match(/^\[Proxy Settings\]\s*\n([\s\S]*?)(?=^\[|$(?![\s\S]))/m)?.[1];if(Z===void 0)return;let J=new Map(Z.split(`
@@ -45,12 +45,12 @@ try {
45
45
  `;$V=yj()});import{Agent as vj}from"node:http";import{Agent as fj}from"node:https";import{Readable as JV}from"node:stream";import hj from"node-fetch";import{HttpProxyAgent as Ij}from"http-proxy-agent";import{HttpsProxyAgent as gj}from"https-proxy-agent";function cj($,Z){if(!Z)return $.protocol==="https:"?pj:mj;return $.protocol==="https:"?new gj(Z):new Ij(Z)}async function lj($,Z,J){if(typeof Bun<"u"){let X=$.protocol==="https:"?"HTTPS_PROXY":"HTTP_PROXY";if(!J&&(process.env[X.toLowerCase()]||process.env[X])){let H=await import("undici");return QV??=new H.Agent,await H.fetch($,{...Z,redirect:"manual",dispatcher:QV})}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 hj($,{method:Q.method,headers:Object.fromEntries(Q.headers),body:Q.body?JV.fromWeb(Q.body):void 0,signal:Q.signal,agent:cj($,J),redirect:"manual"}),V=Q.method==="HEAD"||[204,205,304].includes(Y.status)||!Y.body?null:JV.toWeb(Y.body);return new Response(V,{status:Y.status,statusText:Y.statusText,headers:[...Y.headers]})}async function YV($,Z,J,Q=$V){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&&!f3(Y))throw Error("network: local request must remain on loopback");V.signal?.throwIfAborted();let H=J?void 0:await Q(Y),z=await lj(Y,V,H),G=z.headers.get("location");if(![301,302,303,307,308].includes(z.status)||!G||Z.redirect==="manual")return z;if(await z.body?.cancel(),Z.redirect==="error")throw Error("network: redirect rejected");if(X>=20)throw Error("network: too many redirects");let W=new URL(G,Y),K=new Headers(V.headers);if(W.origin!==Y.origin)for(let j of["authorization","proxy-authorization","cookie","host"])K.delete(j);let _=(V.method??"GET").toUpperCase();if(z.status===303&&_!=="HEAD"||[301,302].includes(z.status)&&_==="POST"){V={...V,method:"GET",body:void 0};for(let j of["content-type","content-length","content-encoding"])K.delete(j)}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 YV($,Z,!1)}function VV($,Z={}){return YV($,Z,!0)}var mj,pj,QV;var o0=R(()=>{ZV();mj=new vj({keepAlive:!0}),pj=new fj({keepAlive:!0})});function C2($){return $!==null&&typeof $==="object"?$:void 0}function O0($){return typeof $==="string"&&$.trim()?$:void 0}function h3($){return typeof $==="number"&&Number.isFinite($)?$:O0($)}function E$($,Z){let J=C2($);if(!J)return;if(typeof J.get==="function"){let Y=O0(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:O0(J[Q])}function n7($){return O0($?.logId)??O0($?.log_id)??O0(C2($?.error)?.log_id)}function F$($){let Z=C2($),J=C2(Z?.response),Q=C2(Z?.data),Y=h3(Z?.code),V=h3(Q?.code),X=typeof Y==="number"||typeof Y==="string"&&/^\d+$/.test(Y)||O0(Z?.apiMessage)!==void 0||O0(Z?.msg)!==void 0,H=V!==0&&V!=="0"&&(V!==void 0||O0(Q?.msg)!==void 0||n7(Q)!==void 0),z=C2(J?.data)??(!X&&H?Q:void 0),G=J?.headers,W=Z?.headers,K=J?.status??Z?.status??Z?.httpStatus;return{code:h3(z?.code)??h3(Z?.code),message:O0(z?.apiMessage)??O0(z?.msg)??O0(z?.message)??O0(Z?.apiMessage)??O0(Z?.msg)??O0(Z?.message)??O0($)??"MISS",logId:n7(z)??n7(Z)??E$(G,"x-tt-logid")??E$(W,"x-tt-logid")??E$(G,"x-request-id")??E$(W,"x-request-id")??E$(G,"request-id")??E$(W,"request-id"),status:typeof K==="number"?K:void 0,retryAfter:O0(Z?.retryAfter)??E$(G,"retry-after")??E$(W,"retry-after")??E$(G,"x-ogw-ratelimit-reset")??E$(W,"x-ogw-ratelimit-reset")}}function k($){let Z=F$($);return`code=${Z.code??"MISS"} message=${Z.message} log_id=${Z.logId??"MISS"}`}import{appendFileSync as zV,mkdirSync as uj,readdirSync as dj,unlinkSync as GV,existsSync as XV,statSync as ij,renameSync as nj,readFileSync as aj}from"node:fs";import{join as WV}from"node:path";function s7($="development"){return $!=="test"}function KV($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Q=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Q}`}function BV($,Z=r){return WV(Z,`${a7}${KV($)}${o7}`)}function sj($){if(!$.startsWith(a7)||!$.endsWith(o7))return null;let Z=$.slice(a7.length,$.length-o7.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 _V($,Z=new Date,J=oj){let Q;try{Q=dj($)}catch{return 0}let Y=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),V=0;for(let X of Q){let H=sj(X);if(!H)continue;if(Math.round((Y.getTime()-H.getTime())/86400000)<J)continue;try{GV(WV($,X)),V++}catch{}}return V}function tj(){try{if(!XV(T2))return;let $=ij(T2);if(!$.isFile()||$.size===0)return;let Z=BV($.mtime);if(XV(Z)){zV(Z,aj(T2)),GV(T2);return}nj(T2,Z)}catch{}}function B($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
46
46
  `;if(process.stderr.write(J),!s7())return;try{let Q=KV(Z);if(HV!==Q)HV=Q,_V(r,Z);zV(BV(Z),J)}catch{}}var oj=7,a7="daemon-",o7=".log",HV=null;var I=R(()=>{V0();if(s7())try{uj(r,{recursive:!0})}catch{}if(s7()){tj();try{_V(r)}catch{}}});function I3($,Z={}){if(!$||typeof $!=="object")return!1;let{status:J,code:Q,message:Y}=F$($);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&&rj.has(J))return!0;if(typeof J==="number"&&J>=400)return!1;if(typeof Q==="string"&&ej.has(Q)||"name"in $&&$.name==="TimeoutError")return!0;return"cause"in $&&$.cause!==$&&I3($.cause,Z)}function $q($){let Z=F$($).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 p1($,Z,J={}){for(let Q=0;;Q++)try{return await Z()}catch(Y){let V=Math.max(t7[Q]??0,$q(Y)),X=I3(Y,J)&&Q<t7.length&&V<=60000;if(B(`feishu: ${$} attempt ${Q+1}/${t7.length+1} failed: ${k(Y)}; ${X?`retry in ${V}ms`:"FINAL"}`),!X){if(!(Y instanceof y0)&&Y&&typeof Y==="object"&&"response"in Y){let H=F$(Y),z=new y0(`${$}: ${k(Y)}`,H.status,H.code,H.retryAfter,H.logId,H.message);throw z.cause=Y,z}throw Y}await new Promise((H)=>setTimeout(H,V))}}async function z$($,Z){let J=await $.text(),Q=$.headers.get("retry-after")??$.headers.get("x-ogw-ratelimit-reset"),Y=F$({headers:$.headers}),V;try{V=JSON.parse(J)}catch{let X=`invalid JSON — ${J.slice(0,200)}`,H={message:X,logId:Y.logId};throw new y0(`${Z} HTTP ${$.status}: ${k(H)}`,$.status,void 0,Q,H.logId,X)}if(!$.ok||V?.code!==0){let X=F$({response:{data:V,headers:$.headers,status:$.status}});throw new y0(`${Z} HTTP ${$.status}: ${k(X)}`,$.status,X.code,Q,X.logId,X.message)}return V}var t7,rj,ej,y0;var b2=R(()=>{I();t7=[1000,4000],rj=new Set([408,429,500,502,503,504]),ej=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 p0($,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 r7($){return $!==null&&typeof $==="object"&&!Array.isArray($)}function jV($){return typeof $==="string"||typeof $==="number"?String($):void 0}async function S$($,Z,J){try{if(!Z.trim())throw Error(`${J}: 请填写 API Key`);return await Zq($,Z,J)}catch(Q){throw Error(p0(Q,[Z]))}}async function Zq($,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=r7(V)?V:void 0,H=r7(X?.error)?X.error:void 0,z=jV(H?.code??H?.type??X?.code),G=jV(H?.message??X?.msg??X?.message??X?.error),W=X?.success===!1||X?.error!=null||z!==void 0&&z!=="0"&&z!=="200";if(!Q.ok||W){let K=[z!==void 0?`code=${z}`:"",G].filter(Boolean).join(": "),_=`${J} HTTP ${Q.status}${K?`: ${K}`:""}`;throw Error(Z?_.replaceAll(Z,"[redacted]"):_)}if(!Array.isArray(X?.data))throw Error(`${J} 缺少 data 数组`);if(!X.data.length)throw Error(`${J} 模型目录为空`);if(!X.data.every(r7))throw Error(`${J} 模型目录包含无效条目`);return X.data}var k2=R(()=>{o0()});function u4($){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 y2($,Z){return(await S$(`${u4($)}/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 w2="https://open.bigmodel.cn/api/anthropic";var d4=R(()=>{k2()});import{chmodSync as Jq,closeSync as e7,fsyncSync as qV,mkdirSync as Qq,openSync as LV,renameSync as Yq,unlinkSync as Vq,writeFileSync as Xq}from"node:fs";import{randomUUID as Hq}from"node:crypto";import{dirname as PV}from"node:path";function Kq($){let Z=PV($);Qq(Z,{recursive:!0,mode:Wq})}function DV($,Z,J){Kq($);let Q=`${$}.${process.pid}.${Hq()}.tmp`,Y=null;try{Y=LV(Q,"wx",J),Xq(Y,Z),qV(Y),e7(Y),Y=null,Yq(Q,$);try{Jq($,J)}catch{}if(process.platform!=="win32"){let V=null;try{V=LV(PV($),"r"),qV(V)}catch{}finally{if(V!==null)try{e7(V)}catch{}}}}catch(V){if(Y!==null)try{e7(Y)}catch{}try{Vq(Q)}catch{}throw V}}function s0($,Z){DV($,Z,zq)}function FV($,Z){DV($,Z,Gq)}function o($,Z){s0($,JSON.stringify(Z,null,2)+`
47
47
  `)}var zq=384,Gq=448,Wq=448;var v0=()=>{};import{execFile as Bq}from"node:child_process";import{spawn as _q}from"cross-spawn";function qq($){if(!Number.isSafeInteger($)||$<=0)return Promise.reject(Error(`Invalid npm installer PID: ${$}`));return new Promise((Z,J)=>{Bq("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 $5($,Z,J={}){Z?.throwIfAborted();let Q=J.platform??process.platform,Y=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,H)=>{let z=(J.spawn??_q)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${jq}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),G="",W,K,_=!1,j=!1,L,q=(A)=>{G=(G+A.toString()).slice(-16384)};z.stdout.on("data",q),z.stderr.on("data",q);let D=(A)=>{if(_)return;if(_=!0,clearTimeout(O),L)clearTimeout(L);if(Z?.removeEventListener("abort",M),A)H(A);else X()},F=(A)=>new g3(`${W?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${A}; partial directory retained: ${$}
49
- ${G}`),U=(A)=>{if(_||j||K)return;W??=Error(A),L=setTimeout(()=>D(F(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(j)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??qq)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((T)=>D(F(T instanceof Error?T.message:String(T))))},M=()=>U("Agent runtime install aborted"),O=setTimeout(()=>U(`Agent runtime install timed out after ${Y}ms`),Y);if(Z?.addEventListener("abort",M,{once:!0}),z.on("error",(A)=>{if(W??=A,!z.pid)D(Error(`${A.message}
50
- ${G}`))}),z.once("close",async(A,T)=>{j=!0,clearTimeout(O),Z?.removeEventListener("abort",M);try{await K}catch(y){D(F(y instanceof Error?y.message:String(y)));return}if(W||A!==0)D(Error(`${W?.message??`npm install exited code=${A} signal=${T}`}
51
- ${G}`));else D()}),Z?.aborted)M()})}var jq="https://registry.npmjs.org",g3;var Z5=R(()=>{g3=class g3 extends Error{}});import{createHash as Lq,randomUUID as Pq}from"node:crypto";import{createRequire as Dq}from"node:module";import{existsSync as m3,readFileSync as MV}from"node:fs";import{mkdir as OV,mkdtemp as Fq,readFile as AV,rename as NV,rm as i4,writeFile as RV}from"node:fs/promises";import{join as t0,isAbsolute as Uq}from"node:path";import{fileURLToPath as Mq,pathToFileURL as Oq}from"node:url";function TV($,Z=I7){let J=t0(Z,$,"current.json");if(!m3(J))return null;let Q=JSON.parse(MV(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!Uq(Q.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Q}function p3($){let Z=TV($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!m3(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function J5($,Z){return Dq(t0(p3($),"package.json")).resolve(Z)}function n4($,Z){let J=t0(p3($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!m3(J))throw Error(`${$} executable missing: ${J}`);return J}async function xV(){return import(Oq(J5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function Tq($,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(`${Rq}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Q.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let H=await X.json();if(H.name!==$||typeof H.version!=="string"||!H.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return H}finally{clearTimeout(V),J?.removeEventListener("abort",Y)}}async function xq($,Z){let J={};if($!=="dsh"){let X=await Promise.all(v2[$].map((H)=>Z(H,"latest")));for(let H of X)J[H.name]=H.version;return J}let Q=await Z("@deepseek-ai/dsh","latest"),Y=new Set(v2.dsh),V=new Set;while(Y.size){let X=[...Y].slice(0,12);for(let z of X)Y.delete(z),V.add(z);let H=await Promise.all(X.map((z)=>z===Q.name?Q:Z(z,Q.version)));for(let z of H){if(z.version!==Q.version)throw Error(`DSH release package mismatch: ${z.name}@${z.version}, expected ${Q.version}`);J[z.name]=z.version;for(let G of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(G.startsWith("@deepseek-ai/dsh")&&!V.has(G))Y.add(G)}}return J}async function W1($,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 Eq($,Z){let J=t0($,`current-${Pq()}.json`),Q;try{await RV(J,JSON.stringify(Z)+`
52
- `,{mode:384}),await W1(()=>NV(J,t0($,"current.json")))}catch(Y){throw Q=Y,Y}finally{try{await W1(()=>i4(J,{force:!0}))}catch(Y){if(Q)throw AggregateError([Q,Y],`${f2(Q)}; state temporary file cleanup failed: ${f2(Y)}`);throw Y}}}async function UV($,Z){for(let[J,Q]of Object.entries(Z)){let Y=JSON.parse(await AV(t0($,"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 Sq($,Z){let J=t0($,"update.lock"),Q=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await OV(J);try{await W1(async()=>s0(t0(J,"pid"),String(process.pid)))}catch(Y){try{await W1(()=>i4(J,{recursive:!0}))}catch(V){throw AggregateError([Y,V],`${f2(Y)}; runtime update lock cleanup failed: ${f2(V)}`)}throw Y}return()=>W1(()=>i4(J,{recursive:!0}))}catch(Y){if(Y.code!=="EEXIST")throw Y;try{let V=Number(await AV(t0(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 W1(()=>i4(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 c3($,Z={}){let J=Z.root??I7,Q=t0(J,$);await OV(Q,{recursive:!0,mode:448});let Y=await Sq(Q,Z.signal),V,X,H=!1;try{let z=TV($,J);Z.report?.(`${$}: 检查 upstream latest`);let G=await xq($,Z.metadata??((q,D)=>Tq(q,D,Z.signal)));Z.signal?.throwIfAborted();let W=JSON.parse(MV(Mq(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=Lq("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),_=t0(Q,K);if(!m3(_)){V=await Fq(t0(Q,".install-")),await RV(t0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:G[v2[$][0]],private:!0,type:"module",dependencies:Object.fromEntries(v2[$].map((D)=>[D,G[D]])),overrides:{...W,...$==="dsh"?G:{}}})+`
53
- `,{mode:384}),await(Z.install??$5)(V,Z.signal),await UV(V,G),Z.signal?.throwIfAborted();let q=V;await W1(()=>NV(q,_)),V=void 0}else await UV(_,G);let j={directory:_,versions:G,checkedAt:Date.now()},L=z?.directory===_;return await Eq(Q,j),Z.report?.(`${$}: ${v2[$][0]}@${G[v2[$][0]]}${L?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){throw X=z,H=z instanceof g3,z}finally{let z=[];if(V&&!H){let G=V;try{await W1(()=>i4(G,{recursive:!0}))}catch(W){z.push(W)}}try{await Y()}catch(G){z.push(G)}if(z.length){let G=X?[X,...z]:z;throw AggregateError(G,G.map(f2).join("; "))}}}function EV($,Z={}){let J=Aq.filter((Q)=>Z.enabled?.[Q]===!0).map((Q)=>{let Y=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??c3)(Q,{report:$,signal:Y.signal}).catch((H)=>$(`${Q} 自动更新未完成: ${f2(H)}`)).finally(()=>{V=void 0})},Nq);return X.unref(),()=>{clearInterval(X),Y.abort()}});return()=>{for(let Q of J)Q()}}var Aq,Nq=21600000,Rq="https://registry.npmjs.org",v2,f2=($)=>$ instanceof Error?$.message:String($);var h2=R(()=>{o0();V0();Z5();v0();Z5();Aq=["codex","claude","dsh"],v2={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 CV;var SV=R(()=>{CV={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 fV={};d$(fV,{writeClaudeGlmEnv:()=>wV,testFeishuCreds:()=>yV,spawnDaemonDetached:()=>vV,runSetup:()=>lq});import{execFileSync as bq,spawn as u3}from"node:child_process";import{spawn as kq}from"cross-spawn";import{existsSync as Y5,mkdirSync as kV,readFileSync as wq}from"node:fs";import{createInterface as yq}from"node:readline/promises";import{dirname as vq,join as V5}from"node:path";import{homedir as fq}from"node:os";import{fileURLToPath as hq}from"node:url";async function c1($,Z={}){while(!0){let J=Z.default?`${P.dim} [${Z.default}]${P.reset}`:"",Q=(await a4.question(`${P.cyan}? ${P.reset}${$}${J}
48
+ ${Y}${V}`));else Z()})})}async function $5($,Z,J={}){Z?.throwIfAborted();let Q=J.platform??process.platform,Y=J.timeoutMs??300000,V=J.terminationTimeoutMs??1e4;return await new Promise((X,H)=>{let z=(J.spawn??_q)("npm",["install","--prefix",$,"--include=optional","--no-fund","--no-audit",`--registry=${jq}`],{cwd:$,stdio:["ignore","pipe","pipe"],shell:!1,windowsHide:!0}),G="",W,K,_=!1,j=!1,L,q=(A)=>{G=(G+A.toString()).slice(-16384)};z.stdout.on("data",q),z.stderr.on("data",q);let D=(A)=>{if(_)return;if(_=!0,clearTimeout(O),L)clearTimeout(L);if(Z?.removeEventListener("abort",U),A)H(A);else X()},F=(A)=>new g3(`${W?.message??"Agent runtime install failed"}; npm installer PID ${z.pid??"MISS"} termination unconfirmed: ${A}; partial directory retained: ${$}
49
+ ${G}`),M=(A)=>{if(_||j||K)return;W??=Error(A),L=setTimeout(()=>D(F(`stdio did not close within ${V}ms`)),V),K=Promise.resolve().then(async()=>{if(j)throw Error("installer closed before process-tree termination started");if(!z.pid)throw Error("installer PID unavailable");if(Q==="win32")await(J.terminateWindows??qq)(z.pid);else if(!z.kill("SIGTERM"))throw Error("npm installer rejected SIGTERM")}),K.catch((T)=>D(F(T instanceof Error?T.message:String(T))))},U=()=>M("Agent runtime install aborted"),O=setTimeout(()=>M(`Agent runtime install timed out after ${Y}ms`),Y);if(Z?.addEventListener("abort",U,{once:!0}),z.on("error",(A)=>{if(W??=A,!z.pid)D(Error(`${A.message}
50
+ ${G}`))}),z.once("close",async(A,T)=>{j=!0,clearTimeout(O),Z?.removeEventListener("abort",U);try{await K}catch(y){D(F(y instanceof Error?y.message:String(y)));return}if(W||A!==0)D(Error(`${W?.message??`npm install exited code=${A} signal=${T}`}
51
+ ${G}`));else D()}),Z?.aborted)U()})}var jq="https://registry.npmjs.org",g3;var Z5=R(()=>{g3=class g3 extends Error{}});import{createHash as Lq,randomUUID as Pq}from"node:crypto";import{createRequire as Dq}from"node:module";import{existsSync as m3,readFileSync as UV}from"node:fs";import{mkdir as OV,mkdtemp as Fq,readFile as AV,rename as NV,rm as i4,writeFile as RV}from"node:fs/promises";import{join as t0,isAbsolute as Mq}from"node:path";import{fileURLToPath as Uq,pathToFileURL as Oq}from"node:url";function TV($,Z=I7){let J=t0(Z,$,"current.json");if(!m3(J))return null;let Q=JSON.parse(UV(J,"utf8"));if(!Number.isFinite(Q.checkedAt)||Q.directory!==void 0&&!Mq(Q.directory))throw Error(`Invalid ${$} runtime state: ${J}`);return Q}function p3($){let Z=TV($);if(!Z?.directory)throw Error(`${$} runtime 未安装,请运行 lodestar-update --agents-only`);if(!m3(Z.directory))throw Error(`${$} runtime 安装目录不存在: ${Z.directory};请运行 lodestar-update --agents-only`);return Z.directory}function J5($,Z){return Dq(t0(p3($),"package.json")).resolve(Z)}function n4($,Z){let J=t0(p3($),"node_modules",".bin",`${Z}${process.platform==="win32"?".cmd":""}`);if(!m3(J))throw Error(`${$} executable missing: ${J}`);return J}async function xV(){return import(Oq(J5("claude","@anthropic-ai/claude-agent-sdk")).href)}async function Tq($,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(`${Rq}/${encodeURIComponent($)}/${encodeURIComponent(Z)}`,{signal:Q.signal});if(!X.ok)throw Error(`${$}@${Z}: npm HTTP ${X.status}`);let H=await X.json();if(H.name!==$||typeof H.version!=="string"||!H.version)throw Error(`Invalid npm manifest: ${$}@${Z}`);return H}finally{clearTimeout(V),J?.removeEventListener("abort",Y)}}async function xq($,Z){let J={};if($!=="dsh"){let X=await Promise.all(v2[$].map((H)=>Z(H,"latest")));for(let H of X)J[H.name]=H.version;return J}let Q=await Z("@deepseek-ai/dsh","latest"),Y=new Set(v2.dsh),V=new Set;while(Y.size){let X=[...Y].slice(0,12);for(let z of X)Y.delete(z),V.add(z);let H=await Promise.all(X.map((z)=>z===Q.name?Q:Z(z,Q.version)));for(let z of H){if(z.version!==Q.version)throw Error(`DSH release package mismatch: ${z.name}@${z.version}, expected ${Q.version}`);J[z.name]=z.version;for(let G of Object.keys({...z.dependencies,...z.peerDependencies,...z.optionalDependencies}))if(G.startsWith("@deepseek-ai/dsh")&&!V.has(G))Y.add(G)}}return J}async function W1($,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 Eq($,Z){let J=t0($,`current-${Pq()}.json`),Q;try{await RV(J,JSON.stringify(Z)+`
52
+ `,{mode:384}),await W1(()=>NV(J,t0($,"current.json")))}catch(Y){throw Q=Y,Y}finally{try{await W1(()=>i4(J,{force:!0}))}catch(Y){if(Q)throw AggregateError([Q,Y],`${f2(Q)}; state temporary file cleanup failed: ${f2(Y)}`);throw Y}}}async function MV($,Z){for(let[J,Q]of Object.entries(Z)){let Y=JSON.parse(await AV(t0($,"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 Sq($,Z){let J=t0($,"update.lock"),Q=Date.now()+360000;for(;;){Z?.throwIfAborted();try{await OV(J);try{await W1(async()=>s0(t0(J,"pid"),String(process.pid)))}catch(Y){try{await W1(()=>i4(J,{recursive:!0}))}catch(V){throw AggregateError([Y,V],`${f2(Y)}; runtime update lock cleanup failed: ${f2(V)}`)}throw Y}return()=>W1(()=>i4(J,{recursive:!0}))}catch(Y){if(Y.code!=="EEXIST")throw Y;try{let V=Number(await AV(t0(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 W1(()=>i4(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 c3($,Z={}){let J=Z.root??I7,Q=t0(J,$);await OV(Q,{recursive:!0,mode:448});let Y=await Sq(Q,Z.signal),V,X,H=!1;try{let z=TV($,J);Z.report?.(`${$}: 检查 upstream latest`);let G=await xq($,Z.metadata??((q,D)=>Tq(q,D,Z.signal)));Z.signal?.throwIfAborted();let W=JSON.parse(UV(Uq(new URL("../package.json",import.meta.url)),"utf8")).overrides??{},K=Lq("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),_=t0(Q,K);if(!m3(_)){V=await Fq(t0(Q,".install-")),await RV(t0(V,"package.json"),JSON.stringify({name:`lodestar-runtime-${$}`,version:G[v2[$][0]],private:!0,type:"module",dependencies:Object.fromEntries(v2[$].map((D)=>[D,G[D]])),overrides:{...W,...$==="dsh"?G:{}}})+`
53
+ `,{mode:384}),await(Z.install??$5)(V,Z.signal),await MV(V,G),Z.signal?.throwIfAborted();let q=V;await W1(()=>NV(q,_)),V=void 0}else await MV(_,G);let j={directory:_,versions:G,checkedAt:Date.now()},L=z?.directory===_;return await Eq(Q,j),Z.report?.(`${$}: ${v2[$][0]}@${G[v2[$][0]]}${L?" 已是 latest":" 已更新,新进程使用新版"}`),j}catch(z){throw X=z,H=z instanceof g3,z}finally{let z=[];if(V&&!H){let G=V;try{await W1(()=>i4(G,{recursive:!0}))}catch(W){z.push(W)}}try{await Y()}catch(G){z.push(G)}if(z.length){let G=X?[X,...z]:z;throw AggregateError(G,G.map(f2).join("; "))}}}function EV($,Z={}){let J=Aq.filter((Q)=>Z.enabled?.[Q]===!0).map((Q)=>{let Y=new AbortController,V,X=setInterval(()=>{if(V)return;V=(Z.update??c3)(Q,{report:$,signal:Y.signal}).catch((H)=>$(`${Q} 自动更新未完成: ${f2(H)}`)).finally(()=>{V=void 0})},Nq);return X.unref(),()=>{clearInterval(X),Y.abort()}});return()=>{for(let Q of J)Q()}}var Aq,Nq=21600000,Rq="https://registry.npmjs.org",v2,f2=($)=>$ instanceof Error?$.message:String($);var h2=R(()=>{o0();V0();Z5();v0();Z5();Aq=["codex","claude","dsh"],v2={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 CV;var SV=R(()=>{CV={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 fV={};d$(fV,{writeClaudeGlmEnv:()=>wV,testFeishuCreds:()=>yV,spawnDaemonDetached:()=>vV,runSetup:()=>lq});import{execFileSync as bq,spawn as u3}from"node:child_process";import{spawn as kq}from"cross-spawn";import{existsSync as Y5,mkdirSync as kV,readFileSync as wq}from"node:fs";import{createInterface as yq}from"node:readline/promises";import{dirname as vq,join as V5}from"node:path";import{homedir as fq}from"node:os";import{fileURLToPath as hq}from"node:url";async function c1($,Z={}){while(!0){let J=Z.default?`${P.dim} [${Z.default}]${P.reset}`:"",Q=(await a4.question(`${P.cyan}? ${P.reset}${$}${J}
54
54
  ${P.green}>${P.reset} `)).trim();if(!Q&&Z.default!==void 0)return Z.default;if(!Q&&Z.required){console.log(`${P.red}必填,请重新输入${P.reset}`);continue}return Q}}function Iq($){let Z="═".repeat(58);console.log(`
55
55
  ${P.bold}${P.cyan}╔${Z}╗${P.reset}`),console.log(`${P.bold}${P.cyan}║ ${$.padEnd(54)} ║${P.reset}`),console.log(`${P.bold}${P.cyan}╚${Z}╝${P.reset}
56
56
  `)}function l3($,Z,J){console.log(`
@@ -67,37 +67,37 @@ ${P.bold}启动 daemon...${P.reset}`);let H=await vV(),z=process.platform==="win
67
67
  app_secret = "xxx"
68
68
 
69
69
  `),O}let Z=QL($),J=Z.feishu?.app_id,Q=Z.feishu?.app_secret;if(!J||!Q)throw Error(`lodestar: ${w0} is missing [feishu].app_id / [feishu].app_secret`);let Y=uV(Z.runtime?.projects_root??dV()),V={codex:!1,claude:!1,dsh:!1},X=Z["runtime.agent_auto_update"],H=Z.runtime?.agent_auto_update;if(H!==void 0){if(X)throw Error("lodestar: legacy [runtime].agent_auto_update cannot be combined with [runtime.agent_auto_update]");if(H!=="true"&&H!=="false")throw Error(`lodestar: [runtime].agent_auto_update must be true or false, got "${H}"`);for(let O of["codex","claude","dsh"])V[O]=H==="true";process.stderr.write(`lodestar: 旧 agent_auto_update 总开关已按原值映射为三个开关;请改用 [runtime.agent_auto_update] 的 codex、claude、dsh 配置。
70
- `)}else if(X)for(let[O,A]of Object.entries(X)){if(O!=="codex"&&O!=="claude"&&O!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${O}"`);if(A!=="true"&&A!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${O} must be true or false, got "${A}"`);V[O]=A==="true"}let z=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(z!=="bucket"&&z!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let G=z,W=Z.notify?.bind??"127.0.0.1",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let _=Number.parseInt(K,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let j=(O)=>{let A=Z[O]??{},T={};for(let[y,S]of Object.entries(A))if(typeof S==="string"&&S.length>0)T[y]=S;return T},L=()=>{let O={};for(let[A,T]of Object.entries(Z)){if(!A.startsWith("claude.models."))continue;let S=A.slice(14).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(T)){if(typeof E!=="string"||E.length===0)continue;if(l.trim()==="model")h.model=E}O[S]=h}return O},q=()=>{let O={},A="projects.";for(let[T,y]of Object.entries(Z)){if(!T.startsWith("projects."))continue;let S=T.slice(9).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(y)){if(typeof E!=="string"||E.length===0)continue;switch(l.trim()){case"cwd":h.cwd=E;break;case"setting_sources":h.settingSources=E;break;case"strict_mcp":h.strictMcp=E==="true";break;case"tools":h.tools=E;break;case"load_project_mcp":h.loadProjectMcp=E==="true";break}}O[S]=h}return O},D=()=>{let O={},A="token_source.";for(let[T,y]of Object.entries(Z)){if(!T.startsWith("token_source."))continue;let S=T.slice(13).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(y)){if(typeof E!=="string")continue;let m=l.trim();if(m==="enabled"){if(E!=="true"&&E!=="false")throw Error(`[${T}].enabled 必须为 true 或 false`);h.enabled=E==="true"}else if(m==="default")h.default=E==="true";else if(m==="agent"||m==="display"||m==="auth"||m==="base_url"||m==="auth_token"||m==="api_key"||m==="management_token"||m==="management_user_id"||m==="management_url"||m==="billing_source"||m==="bin"||m==="model"||m==="effort"||m==="models"||m==="hidden_models"||m==="custom_models"||m==="slots"||m==="usage")h[m]=E}O[S]=h}return O},F=j("codex.env"),U=j("claude.env"),M=Z.claude?.bin?uV(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:_},codex:{env:F},claude:{bin:M,env:U,models:L()},projects:q(),token_sources:D()}}function iV(){p.token_sources=t4().token_sources}var p;var f0=R(()=>{V0();p=t4()});function q0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function n$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function t3($){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 XL($){let Z=$.slice(0,_5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function HL($){let Z=a($);if(!Z)return null;let J=a(Z.event),Q=a(Z.payload);return a(Z.item)??a(Z.responseItem)??a(Z.rawItem)??a(J?.item)??a(J?.responseItem)??a(J?.rawItem)??a(Q?.item)??a(Q?.responseItem)??a(Q?.rawItem)??(r4(Z.type)?Z:null)??(J&&r4(J.type)?J:null)??(Q&&r4(Q.type)?Q:null)}function zL($){let Z=[],J=new WeakSet,Q=(Y,V,X)=>{if(Z.length>=_5||X>6)return;if(Array.isArray(Y)){if(V)Z.push(`${V}[]`);if(Y.length>0)Q(Y[0],V?`${V}[]`:"[]",X+1);return}if(Y==null||typeof Y!=="object")return;if(J.has(Y))return;J.add(Y);for(let H of Object.keys(Y)){if(Z.length>=_5)return;let z=V?`${V}.${H}`:H;Z.push(z),Q(Y[H],z,X+1)}};return Q($,"",0),Z}function j5($){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>B5)return`${Y.slice(0,B5)}...<truncated ${Y.length-B5} 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>K5)return`${J.slice(0,K5)}...<truncated ${J.length-K5} chars>`;return J}function r0($,Z){let J=a(Z),Q=J?a(J.params):null,Y=J?a(J.item)??a(Q?.item):null,V=J?q0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${n$(V)}`,`rootKeys=${t3(J)}`,`itemKeys=${t3(Y)}`,`payload=${j5(Z)}`].join(" "))}function q5($,Z,J){let Q=a(Z),Y=HL(Z),V=[`phase=${n$(J.phase??"event")}`,`method=${n$($)}`,`sourceMethod=${n$(J.sourceMethod)}`,`sourceType=${n$(J.sourceType)}`,`sessionId=${n$(J.sessionId)}`,`threadId=${n$(J.threadId)}`,`turnId=${n$(J.turnId)}`,`itemId=${n$(J.itemId)}`].join(" ");if(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${t3(Q)} itemKeys=${t3(Y)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${XL(zL(Z))}`),Y)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${j5(Y)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${j5(Z)}`)}function r4($){if(typeof $!=="string")return null;return VL.has($)?$:null}function GL($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||nV.has(Z))return"end";return"event"}function L5($,Z){return aV($,a(Z)??{})}function P5($){let Z=a($);if(!Z)return null;let J=q0(Z.method)??q0(Z.type)??"raw_message";return aV(J,Z)}function aV($,Z){let J=a(Z.payload),Q=[Z,a(Z.event),J,a(Z.item),a(Z.responseItem),a(Z.rawItem)].filter((z)=>z!=null),Y=null;for(let z of Q)if(Y=r4(z.type),Y)break;if(!nV.has($)&&!Y)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),X=Y==="compacted"&&J?J:V&&r4(V.type)?V:Z,H=a(X.item)??a(X.responseItem)??a(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(H.id)??q0(H.itemId)??q0(H.item_id),timestamp:q0(Z.timestamp)??q0(X.timestamp),recordType:q0(Z.type),phase:GL(Y,$),sourceMethod:$,sourceType:Y??$}}var nV,VL,K5=200000,B5=50000,_5=400;var D5=R(()=>{I();nV=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),VL=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function e4($){return $!=null&&typeof $==="object"?$:null}function a$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function oV($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function r3($,Z){return $?a$($[Z]):void 0}function c2($){let Z=e4($);if(!Z)return null;let J=e4(Z.inputTokensDetails)??e4(Z.input_tokens_details),Q=e4(Z.outputTokensDetails)??e4(Z.output_tokens_details),Y={total_tokens:a$(Z.totalTokens??Z.total_tokens),input_tokens:a$(Z.inputTokens??Z.input_tokens),output_tokens:a$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:a$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??r3(Q,"reasoningTokens")??r3(Q,"reasoning_tokens")),cache_creation_input_tokens:a$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:a$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??r3(J,"cachedTokens")??r3(J,"cached_tokens"))};return oV(Y)?Y:null}function F5($,Z){let J=(Y)=>{let V=a$($?.[Y]),X=a$(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 oV(Q)?Q:null}function U5($){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 sV($){let Z=$.trim();if(Z.length<2)return Z;let J=e3[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 O5($){let Z=KL(String($??"")),J=Z.split(`
70
+ `)}else if(X)for(let[O,A]of Object.entries(X)){if(O!=="codex"&&O!=="claude"&&O!=="dsh")throw Error(`lodestar: unknown [runtime.agent_auto_update] Agent "${O}"`);if(A!=="true"&&A!=="false")throw Error(`lodestar: [runtime.agent_auto_update].${O} must be true or false, got "${A}"`);V[O]=A==="true"}let z=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(z!=="bucket"&&z!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let G=z,W=Z.notify?.bind??"127.0.0.1",K=Z.notify?.port??"9876";if(!/^\d+$/.test(K.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${K}"`);let _=Number.parseInt(K,10);if(!Number.isFinite(_)||_<=0||_>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${K}"`);let j=(O)=>{let A=Z[O]??{},T={};for(let[y,S]of Object.entries(A))if(typeof S==="string"&&S.length>0)T[y]=S;return T},L=()=>{let O={};for(let[A,T]of Object.entries(Z)){if(!A.startsWith("claude.models."))continue;let S=A.slice(14).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(T)){if(typeof E!=="string"||E.length===0)continue;if(l.trim()==="model")h.model=E}O[S]=h}return O},q=()=>{let O={},A="projects.";for(let[T,y]of Object.entries(Z)){if(!T.startsWith("projects."))continue;let S=T.slice(9).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(y)){if(typeof E!=="string"||E.length===0)continue;switch(l.trim()){case"cwd":h.cwd=E;break;case"setting_sources":h.settingSources=E;break;case"strict_mcp":h.strictMcp=E==="true";break;case"tools":h.tools=E;break;case"load_project_mcp":h.loadProjectMcp=E==="true";break}}O[S]=h}return O},D=()=>{let O={},A="token_source.";for(let[T,y]of Object.entries(Z)){if(!T.startsWith("token_source."))continue;let S=T.slice(13).trim();if(!S)continue;let h={};for(let[l,E]of Object.entries(y)){if(typeof E!=="string")continue;let m=l.trim();if(m==="enabled"){if(E!=="true"&&E!=="false")throw Error(`[${T}].enabled 必须为 true 或 false`);h.enabled=E==="true"}else if(m==="default")h.default=E==="true";else if(m==="agent"||m==="display"||m==="auth"||m==="base_url"||m==="auth_token"||m==="api_key"||m==="management_token"||m==="management_user_id"||m==="management_url"||m==="billing_source"||m==="bin"||m==="model"||m==="effort"||m==="models"||m==="hidden_models"||m==="custom_models"||m==="slots"||m==="usage")h[m]=E}O[S]=h}return O},F=j("codex.env"),M=j("claude.env"),U=Z.claude?.bin?uV(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:_},codex:{env:F},claude:{bin:U,env:M,models:L()},projects:q(),token_sources:D()}}function iV(){p.token_sources=t4().token_sources}var p;var f0=R(()=>{V0();p=t4()});function q0($){return typeof $==="string"&&$?$:void 0}function a($){return $!=null&&typeof $==="object"?$:null}function n$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function t3($){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 XL($){let Z=$.slice(0,_5),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function HL($){let Z=a($);if(!Z)return null;let J=a(Z.event),Q=a(Z.payload);return a(Z.item)??a(Z.responseItem)??a(Z.rawItem)??a(J?.item)??a(J?.responseItem)??a(J?.rawItem)??a(Q?.item)??a(Q?.responseItem)??a(Q?.rawItem)??(r4(Z.type)?Z:null)??(J&&r4(J.type)?J:null)??(Q&&r4(Q.type)?Q:null)}function zL($){let Z=[],J=new WeakSet,Q=(Y,V,X)=>{if(Z.length>=_5||X>6)return;if(Array.isArray(Y)){if(V)Z.push(`${V}[]`);if(Y.length>0)Q(Y[0],V?`${V}[]`:"[]",X+1);return}if(Y==null||typeof Y!=="object")return;if(J.has(Y))return;J.add(Y);for(let H of Object.keys(Y)){if(Z.length>=_5)return;let z=V?`${V}.${H}`:H;Z.push(z),Q(Y[H],z,X+1)}};return Q($,"",0),Z}function j5($){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>B5)return`${Y.slice(0,B5)}...<truncated ${Y.length-B5} 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>K5)return`${J.slice(0,K5)}...<truncated ${J.length-K5} chars>`;return J}function r0($,Z){let J=a(Z),Q=J?a(J.params):null,Y=J?a(J.item)??a(Q?.item):null,V=J?q0(J.method)??"-":"-";B([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${n$(V)}`,`rootKeys=${t3(J)}`,`itemKeys=${t3(Y)}`,`payload=${j5(Z)}`].join(" "))}function q5($,Z,J){let Q=a(Z),Y=HL(Z),V=[`phase=${n$(J.phase??"event")}`,`method=${n$($)}`,`sourceMethod=${n$(J.sourceMethod)}`,`sourceType=${n$(J.sourceType)}`,`sessionId=${n$(J.sessionId)}`,`threadId=${n$(J.threadId)}`,`turnId=${n$(J.turnId)}`,`itemId=${n$(J.itemId)}`].join(" ");if(B(`codex-process: CONTEXT_COMPACTION_EVENT ${V} rootKeys=${t3(Q)} itemKeys=${t3(Y)}`),B(`codex-process: CONTEXT_COMPACTION_PATHS ${V} paths=${XL(zL(Z))}`),Y)B(`codex-process: CONTEXT_COMPACTION_ITEM ${V} item=${j5(Y)}`);B(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${V} payload=${j5(Z)}`)}function r4($){if(typeof $!=="string")return null;return VL.has($)?$:null}function GL($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||nV.has(Z))return"end";return"event"}function L5($,Z){return aV($,a(Z)??{})}function P5($){let Z=a($);if(!Z)return null;let J=q0(Z.method)??q0(Z.type)??"raw_message";return aV(J,Z)}function aV($,Z){let J=a(Z.payload),Q=[Z,a(Z.event),J,a(Z.item),a(Z.responseItem),a(Z.rawItem)].filter((z)=>z!=null),Y=null;for(let z of Q)if(Y=r4(z.type),Y)break;if(!nV.has($)&&!Y)return null;let V=a(Z.item)??a(Z.responseItem)??a(Z.rawItem),X=Y==="compacted"&&J?J:V&&r4(V.type)?V:Z,H=a(X.item)??a(X.responseItem)??a(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(H.id)??q0(H.itemId)??q0(H.item_id),timestamp:q0(Z.timestamp)??q0(X.timestamp),recordType:q0(Z.type),phase:GL(Y,$),sourceMethod:$,sourceType:Y??$}}var nV,VL,K5=200000,B5=50000,_5=400;var D5=R(()=>{I();nV=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),VL=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function e4($){return $!=null&&typeof $==="object"?$:null}function a$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function oV($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function r3($,Z){return $?a$($[Z]):void 0}function c2($){let Z=e4($);if(!Z)return null;let J=e4(Z.inputTokensDetails)??e4(Z.input_tokens_details),Q=e4(Z.outputTokensDetails)??e4(Z.output_tokens_details),Y={total_tokens:a$(Z.totalTokens??Z.total_tokens),input_tokens:a$(Z.inputTokens??Z.input_tokens),output_tokens:a$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:a$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??r3(Q,"reasoningTokens")??r3(Q,"reasoning_tokens")),cache_creation_input_tokens:a$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:a$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??r3(J,"cachedTokens")??r3(J,"cached_tokens"))};return oV(Y)?Y:null}function F5($,Z){let J=(Y)=>{let V=a$($?.[Y]),X=a$(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 oV(Q)?Q:null}function M5($){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 sV($){let Z=$.trim();if(Z.length<2)return Z;let J=e3[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 O5($){let Z=KL(String($??"")),J=Z.split(`
71
71
  `,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
72
  `).slice(1).join(`
73
73
  `).trimStart():Z;return{description:Y,command:V||Z}}function l2($,Z=60){let{description:J,command:Q}=O5($);if(J)return J;return WL(Q).replace(/\s+/g," ").trim().slice(0,Z)}function WL($){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 KL($){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=_L(J[1]);return M5(Y||Z)}let Q=BL(Z);if(Q)return Q;return M5(Z)}function BL($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=sV(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 M5(sV(Y[2]));if(Q=Y[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function _L($){let Z=$.trim();if(Z.length<2)return Z;let J=e3[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 M5($){let Z=$.trim(),J=Z[0];if(!e3[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!jL(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,H)=>` $(${H})`)}function jL($,Z){let J=e3[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 e3;var $8=R(()=>{e3={'"':'"',"'":"'","“":"”"}});function tV($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function x($){return $ instanceof Error?$.message:String($)}function x0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as rV}from"node:path";function qL($){return $.kind==="fresh"?null:$.source.provider}function U0($,Z,J){let Q=qL($);if(Q&&Q!==Z)throw Error(`conversation launch provider mismatch: source=${Q} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!rV($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!rV(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 u1=()=>{};import{existsSync as LL,readFileSync as PL}from"node:fs";function eV($,Z){return`${$}:${Z}`}function DL(){if(!LL(x3))return;try{let $=JSON.parse(PL(x3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");$9=new Set($.ids)}catch($){A5=$ instanceof Error?$:Error(String($))}}function $X(){if(A5)throw Error(`delegated-agent session registry is unavailable: ${A5.message}`)}function ZX($,Z){$X();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Q=eV($,J);if($9.has(Q))return;let Y=new Set($9);Y.add(Q),o(x3,{version:1,ids:[...Y].sort()}),$9=Y}function u2($,Z){return $X(),$9.has(eV($,Z))}var $9,A5=null;var Z9=R(()=>{V0();v0();$9=new Set;DL()});function N5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function FL($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function d1($,Z){let J=$.buckets?.find((Q)=>Q.limitName?.toLowerCase()===Z.toLowerCase()||Q.normalModelSlug===Z)??$;return{...J,fiveHour:N5($.subscriptionType,J.fiveHour)}}function Z8($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=d1($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function UL($,Z){let J=d1($,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+604800000&&Y<=Math.floor($.fetchedAt/1000)*1000+604800000}function JX($,Z,J){let Q=d1($,Z).weekly?.resetsAt?.getTime();return Q!=null&&Q-604800000<=J}function J8($,Z){let J=(Q)=>Q.priority==="unused"?2:Q.priority==="expiring"?1:0;return J(Z)-J($)||($.priority==="expiring"?$.hours-Z.hours:Z.score-$.score)||(Z.availableNow??0)-($.availableNow??0)||$.account.id.localeCompare(Z.account.id)}function R5($,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=FL($.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=d1($,Z),H=[X.fiveHour,X.weekly].filter((D)=>D!==null),z=H.filter((D)=>D.percent!==null&&D.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||X.rateLimitReachedType||X.spendControlReached===!0){let D=z.map((F)=>F.resetsAt?.getTime()).filter((F)=>F!=null&&Number.isFinite(F)&&F>J);return{...Y,state:"exhausted",reason:"额度耗尽",...D.length===z.length&&D.length?{retryAt:Math.max(...D)}:{}}}if(H.some((D)=>D.percent===null||!Number.isFinite(D.percent)||D.percent<0))return{...Y,reason:"额度百分比 MISS"};let G=X.weekly;if(!G||G.percent===null)return{...Y,reason:"周额度 MISS"};let W=G.resetsAt?.getTime();if(W==null||!Number.isFinite(W)||W<=J)return{...Y,reason:"周重置时间 MISS 或已过期"};let K=V*(100-G.percent)/100,_=(W-J)/3600000,j=_-5,L=j>0?K/j:null;if(Q==="ultra"&&K<0.5)return{...Y,state:"waiting",remaining:K,hours:_,weeklyScore:L,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:W};let q=j<=0?"expiring":UL($,Z)?"unused":void 0;if($.subscriptionType==="plus"){let D=X.fiveHour,F=0.15*(100-D.percent)/100,U=D.unreportedFull?5:((D.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(U)||U<=0)return{...Y,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:K,hours:_,priority:q,weeklyScore:L,fiveHourRemaining:F,fiveHourHours:U,availableNow:Math.min(K,F),score:L===null?null:Math.min(L,F/U)}}return{state:"ready",shares:V,remaining:K,hours:_,priority:q,weeklyScore:L,availableNow:K,score:L}}function Q8($){if(!$||typeof $!=="object")return!1;let Z=$;if(Z.codexErrorInfo==="usageLimitExceeded"||Z.type==="usage_limit_reached"||Z.code==="usage_limit_reached")return!0;return typeof Z.message==="string"&&/^You(?:'|’)ve hit your usage limit\b/i.test(Z.message)}import{closeSync as ML,existsSync as OL,mkdirSync as AL,openSync as NL,readdirSync as RL,readSync as TL,statSync as V8,writeFileSync as xL}from"node:fs";import{homedir as T5}from"node:os";import{delimiter as QX,isAbsolute as YX,join as _1}from"node:path";import{EventEmitter as EL}from"node:events";import{StringDecoder as VX}from"node:string_decoder";import{spawn as SL}from"cross-spawn";function J9(){return n4("codex","codex")}function CL(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([_1(T5(),".local","npm-global","bin"),_1(T5(),".local","bin"),_1(T5(),".bun","bin"),...(process.env.PATH??"").split(QX),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(QX)}function HX($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function hL($){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 IL($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function gL($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function W$($){return typeof $==="string"&&Q9.includes($)}function mL($){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(!W$(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 x5($,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:E5($)}}return null}function pL($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function E5($){return{status:$.status,revisedPrompt:pL($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function zX($){if(!$||!OL(XX))return null;let Z=null,J=[XX];while(J.length){let Q=J.pop(),Y;try{Y=RL(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=_1(Q,V.name);if(V.isDirectory()){J.push(X);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let H=V8(X).mtimeMs;if(!Z||H>Z.mtimeMs)Z={path:X,mtimeMs:H}}catch(H){B(`codex-process: cannot stat Codex rollout ${X}: ${H instanceof Error?H.message:H}`)}}}return Z?.path??null}function BX($,Z,J=bL){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let V=cL($,Z,J);if(V)return V;if(Y.length>2048){let X=_X($);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 cL($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=lL(Q);if(!Y)return null;let V=GX(Z??"unknown-thread"),X=GX(_X($)),H=_1(J,V),z=_1(H,`${X}.${Y.ext}`);try{return AL(H,{recursive:!0}),xL(z,Y.buffer),z}catch(G){return B(`codex-process: failed to write image generation result ${z}: ${G instanceof Error?G.message:G}`),null}}function _X($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function GX($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function lL($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=dL(Y[1]),J=Y[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let V=J.padEnd(Math.ceil(J.length/4)*4,"="),X;try{X=Buffer.from(V,"base64")}catch{return null}if(X.length<12)return null;let H=uL(X)??Q;if(!H)return null;return{buffer:X,ext:H}}function uL($){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 dL($){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 WX($,Z,J){let Q=x5($,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:BX($,J),isError:$.status==="failed"}}return null}function Y8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return x0(Z)}function KX($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function iL($,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 l2(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 jX($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function nL($){let Z=jX($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function aL($){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(`${x0(Q)}: ${X}`)}return J.join(`
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=_L(J[1]);return U5(Y||Z)}let Q=BL(Z);if(Q)return Q;return U5(Z)}function BL($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=sV(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 U5(sV(Y[2]));if(Q=Y[2],V==="-executionpolicy"||V==="-inputformat"||V==="-outputformat")Q=Q.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function _L($){let Z=$.trim();if(Z.length<2)return Z;let J=e3[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 U5($){let Z=$.trim(),J=Z[0];if(!e3[J])return Z;let Q=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Q)&&!jL(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,H)=>` $(${H})`)}function jL($,Z){let J=e3[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 e3;var $8=R(()=>{e3={'"':'"',"'":"'","“":"”"}});function tV($,Z){return $?.then(async(J)=>{return await Z(J),J.ok?"complete":"retry"})??null}function x($){return $ instanceof Error?$.message:String($)}function x0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}import{isAbsolute as rV}from"node:path";function qL($){return $.kind==="fresh"?null:$.source.provider}function M0($,Z,J){let Q=qL($);if(Q&&Q!==Z)throw Error(`conversation launch provider mismatch: source=${Q} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!rV($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!rV(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 u1=()=>{};import{existsSync as LL,readFileSync as PL}from"node:fs";function eV($,Z){return`${$}:${Z}`}function DL(){if(!LL(x3))return;try{let $=JSON.parse(PL(x3,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");$9=new Set($.ids)}catch($){A5=$ instanceof Error?$:Error(String($))}}function $X(){if(A5)throw Error(`delegated-agent session registry is unavailable: ${A5.message}`)}function ZX($,Z){$X();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Q=eV($,J);if($9.has(Q))return;let Y=new Set($9);Y.add(Q),o(x3,{version:1,ids:[...Y].sort()}),$9=Y}function u2($,Z){return $X(),$9.has(eV($,Z))}var $9,A5=null;var Z9=R(()=>{V0();v0();$9=new Set;DL()});function N5($,Z){return $==="plus"&&Z===null?{percent:0,resetsAt:null,durationMins:300,unreportedFull:!0}:Z}function FL($){switch($){case"plus":return 1;case"prolite":return 5;case"pro":return 20;default:return null}}function d1($,Z){let J=$.buckets?.find((Q)=>Q.limitName?.toLowerCase()===Z.toLowerCase()||Q.normalModelSlug===Z)??$;return{...J,fiveHour:N5($.subscriptionType,J.fiveHour)}}function Z8($,Z){if($.state!=="ok")throw Error("额度计量桶 MISS");let J=d1($,Z);return"limitId"in J?J.limitId:$.defaultLimitId??"codex"}function ML($,Z){let J=d1($,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+604800000&&Y<=Math.floor($.fetchedAt/1000)*1000+604800000}function JX($,Z,J){let Q=d1($,Z).weekly?.resetsAt?.getTime();return Q!=null&&Q-604800000<=J}function J8($,Z){let J=(Q)=>Q.priority==="unused"?2:Q.priority==="expiring"?1:0;return J(Z)-J($)||($.priority==="expiring"?$.hours-Z.hours:Z.score-$.score)||(Z.availableNow??0)-($.availableNow??0)||$.account.id.localeCompare(Z.account.id)}function R5($,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=FL($.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=d1($,Z),H=[X.fiveHour,X.weekly].filter((D)=>D!==null),z=H.filter((D)=>D.percent!==null&&D.percent>=100);if(z.length||$.ordinaryUsageAllowed===!1||X.rateLimitReachedType||X.spendControlReached===!0){let D=z.map((F)=>F.resetsAt?.getTime()).filter((F)=>F!=null&&Number.isFinite(F)&&F>J);return{...Y,state:"exhausted",reason:"额度耗尽",...D.length===z.length&&D.length?{retryAt:Math.max(...D)}:{}}}if(H.some((D)=>D.percent===null||!Number.isFinite(D.percent)||D.percent<0))return{...Y,reason:"额度百分比 MISS"};let G=X.weekly;if(!G||G.percent===null)return{...Y,reason:"周额度 MISS"};let W=G.resetsAt?.getTime();if(W==null||!Number.isFinite(W)||W<=J)return{...Y,reason:"周重置时间 MISS 或已过期"};let K=V*(100-G.percent)/100,_=(W-J)/3600000,j=_-5,L=j>0?K/j:null;if(Q==="ultra"&&K<0.5)return{...Y,state:"waiting",remaining:K,hours:_,weeklyScore:L,reason:`Ultra 至少需要 ${0.5} 份周余量`,retryAt:W};let q=j<=0?"expiring":ML($,Z)?"unused":void 0;if($.subscriptionType==="plus"){let D=X.fiveHour,F=0.15*(100-D.percent)/100,M=D.unreportedFull?5:((D.resetsAt?.getTime()??NaN)-J)/3600000;if(!Number.isFinite(M)||M<=0)return{...Y,reason:"5h 重置时间 MISS 或已过期"};return{state:"ready",shares:V,remaining:K,hours:_,priority:q,weeklyScore:L,fiveHourRemaining:F,fiveHourHours:M,availableNow:Math.min(K,F),score:L===null?null:Math.min(L,F/M)}}return{state:"ready",shares:V,remaining:K,hours:_,priority:q,weeklyScore:L,availableNow:K,score:L}}function Q8($){if(!$||typeof $!=="object")return!1;let Z=$;if(Z.codexErrorInfo==="usageLimitExceeded"||Z.type==="usage_limit_reached"||Z.code==="usage_limit_reached")return!0;return typeof Z.message==="string"&&/^You(?:'|’)ve hit your usage limit\b/i.test(Z.message)}import{closeSync as UL,existsSync as OL,mkdirSync as AL,openSync as NL,readdirSync as RL,readSync as TL,statSync as V8,writeFileSync as xL}from"node:fs";import{homedir as T5}from"node:os";import{delimiter as QX,isAbsolute as YX,join as _1}from"node:path";import{EventEmitter as EL}from"node:events";import{StringDecoder as VX}from"node:string_decoder";import{spawn as SL}from"cross-spawn";function J9(){return n4("codex","codex")}function CL(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([_1(T5(),".local","npm-global","bin"),_1(T5(),".local","bin"),_1(T5(),".bun","bin"),...(process.env.PATH??"").split(QX),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(QX)}function HX($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function hL($){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 IL($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function gL($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function W$($){return typeof $==="string"&&Q9.includes($)}function mL($){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(!W$(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 x5($,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:E5($)}}return null}function pL($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function E5($){return{status:$.status,revisedPrompt:pL($),...typeof $?.prompt==="string"&&$.prompt?{prompt:$.prompt}:{}}}function zX($){if(!$||!OL(XX))return null;let Z=null,J=[XX];while(J.length){let Q=J.pop(),Y;try{Y=RL(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=_1(Q,V.name);if(V.isDirectory()){J.push(X);continue}if(!V.isFile())continue;if(!V.name.startsWith("rollout-")||!V.name.endsWith(`${$}.jsonl`))continue;try{let H=V8(X).mtimeMs;if(!Z||H>Z.mtimeMs)Z={path:X,mtimeMs:H}}catch(H){B(`codex-process: cannot stat Codex rollout ${X}: ${H instanceof Error?H.message:H}`)}}}return Z?.path??null}function BX($,Z,J=bL){let Q=$?.savedPath??$?.saved_path;if(typeof Q==="string"&&Q)return Q;let Y=$?.result;if(typeof Y==="string"){let V=cL($,Z,J);if(V)return V;if(Y.length>2048){let X=_X($);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 cL($,Z,J){let Q=$?.result;if(typeof Q!=="string")return null;let Y=lL(Q);if(!Y)return null;let V=GX(Z??"unknown-thread"),X=GX(_X($)),H=_1(J,V),z=_1(H,`${X}.${Y.ext}`);try{return AL(H,{recursive:!0}),xL(z,Y.buffer),z}catch(G){return B(`codex-process: failed to write image generation result ${z}: ${G instanceof Error?G.message:G}`),null}}function _X($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function GX($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function lL($){let Z=$.trim(),J=Z,Q=null,Y=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Y)Q=dL(Y[1]),J=Y[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let V=J.padEnd(Math.ceil(J.length/4)*4,"="),X;try{X=Buffer.from(V,"base64")}catch{return null}if(X.length<12)return null;let H=uL(X)??Q;if(!H)return null;return{buffer:X,ext:H}}function uL($){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 dL($){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 WX($,Z,J){let Q=x5($,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:BX($,J),isError:$.status==="failed"}}return null}function Y8($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return x0(Z)}function KX($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function iL($,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 l2(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 jX($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function nL($){let Z=jX($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function aL($){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(`${x0(Q)}: ${X}`)}return J.join(`
77
77
  `)}var XX,bL,kL=30000,wL=600000,yL=5000,vL=60000,fL="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",Q9,Y9="xhigh",d2,i2;var j1=R(()=>{f0();I();h2();D5();$8();u1();Z9();D0();D5();XX=_1(v.defaultHome,"sessions"),bL=_1(v.defaultHome,"generated_images");Q9=["none","minimal","low","medium","high","xhigh","max","ultra"];d2=class d2 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"}};i2=class i2 extends EL{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 VX("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=J9(),J=[...IL($.allowDelegation!==!1),...$.apiProvider?hL($.apiProvider):[...$.tokenSourceId==="codex-sub"?["-c",'model_provider="openai"']:[],...v.cliArgs($.codexAccountId??c)]];B(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Q={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:CL(),...p.codex.env,...$.hostEnv??{}},Y=$.transformEnv?$.transformEnv(Q):Q,V=$.apiProvider?{...Y,CODEX_HOME:v.defaultHome}:v.env($.codexAccountId??c,Y);if(this.proc=SL(Z,J,gL($.workDir,V)),this.proc.stdout.on("data",(X)=>this.onStdout(X)),this.proc.stderr.on("data",(X)=>this.onStderr(X)),this.proc.stdin.on("error",(X)=>this.handleStdinError(X)),this.proc.on("exit",(X,H)=>this.handleChildExit(X,H)),this.proc.on("close",(X,H)=>this.handleChildClose(X,H)),this.proc.on("error",(X)=>this.handleChildProcessError(X)),!$.apiProvider)K1(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(`
78
78
  `))>=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
79
  `))}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 d2(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=P5($);if(Z){let J=this.withSessionId(Z);q5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}r0("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=L5($,Z);if(J){let Q=this.withSessionId(J);q5($,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(W$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=c2(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=c2(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){r0("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){r0("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 r0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Q.status,X=Q.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Y?this.turnError.error:null);this.turnError=null;let H=V==="failed"||!!X,z=V==="completed"&&!H&&!!Y;if(this.lastCompletedTurnId=z?Y:null,this.currentTurnId=null,V==="failed"&&Y&&HX(X?.message)&&this.scheduleCapacityRetry(X.message,fL))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let G=H?X?.type??X?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Q.durationMs==="number"?Q.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:G,is_error:H},this.emit("result",{subtype:G,is_error:H,...H&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Y&&Q8(X)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:z&&this.sessionId?{provider:"codex",kind:"turn",id:Y,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else B("codex-process: thread/goal/updated missing goal");return}case"thread/goal/cleared":{this.emit("thread_goal_cleared",Z);return}case"thread/status/changed":{this.handleThreadStatusChanged(Z);return}case"item/agentMessage/delta":{if(typeof Z.delta==="string"&&Z.delta.length>0)this.emit("assistant_text",{uuid:Z.itemId,text:Z.delta,parentToolUseId:null});else r0("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}}r0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){r0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=x5(Z,this.opts.workDir);if(!J){r0("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){r0("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=WX(Z,this.opts.workDir,this.sessionId??void 0);if(!J){r0("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:E5(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)??x0(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"?x5($,this.opts.workDir):WX($,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:iL(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=Y8($.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=Y8($.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=jX($);for(let Y of Q){if(this.collabAgentSettled.has(Y))continue;if(this.collabAgentSettled.add(Y),!this.collabAgentNames.has(Y))this.collabAgentNames.set(Y,Y8(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:KX($.prompt),description:nL($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:aL($),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($)??Y8(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:KX(J.prompt)};this.emit("bg_task_started",X);let H={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",H)}if(Q==="running"||Q==="pendingInit"||Q==="interrupted"){let V={task_id:$,patch:{status:Q==="pendingInit"?"pending":Q==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",V);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Y={task_id:$,status:Q==="completed"?"completed":Q==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Y)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new VX("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=zX(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=V8($).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??zX(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=V8($).size;if(Y<=this.rolloutReadOffset)return;let V=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=NL($,"r"),H=0;try{while(H<V){let z=TL(X,Z,H,V-H,this.rolloutReadOffset+H);if(z===0)break;H+=z}}finally{ML(X)}Z=Z.subarray(0,H),this.rolloutReadOffset+=H}catch(Y){B(`codex-process: image generation rollout read failed ${$}: ${Y instanceof Error?Y.message:Y}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Q=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
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 d2(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=P5($);if(Z){let J=this.withSessionId(Z);q5(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}r0("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=L5($,Z);if(J){let Q=this.withSessionId(J);q5($,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(W$(Q?.effort))this.lastEffort=Q.effort;return}case"thread/tokenUsage/updated":{let Q=c2(Z.tokenUsage?.last);if(Q)this.lastUsage=Q,this.lastResult.usage=this.lastUsage;else B("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=c2(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){r0("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){r0("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 r0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let V=Q.status,X=Q.error??(V==="failed"&&this.turnError&&this.turnError.turnId===Y?this.turnError.error:null);this.turnError=null;let H=V==="failed"||!!X,z=V==="completed"&&!H&&!!Y;if(this.lastCompletedTurnId=z?Y:null,this.currentTurnId=null,V==="failed"&&Y&&HX(X?.message)&&this.scheduleCapacityRetry(X.message,fL))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let G=H?X?.type??X?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Q.durationMs==="number"?Q.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:G,is_error:H},this.emit("result",{subtype:G,is_error:H,...H&&typeof X?.message==="string"?{error:X.message}:{},...V==="failed"&&Y&&Q8(X)?{codexQuotaFailure:{accepted:!0}}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Y,checkpoint:z&&this.sessionId?{provider:"codex",kind:"turn",id:Y,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else B("codex-process: thread/goal/updated missing goal");return}case"thread/goal/cleared":{this.emit("thread_goal_cleared",Z);return}case"thread/status/changed":{this.handleThreadStatusChanged(Z);return}case"item/agentMessage/delta":{if(typeof Z.delta==="string"&&Z.delta.length>0)this.emit("assistant_text",{uuid:Z.itemId,text:Z.delta,parentToolUseId:null});else r0("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}}r0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){r0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=x5(Z,this.opts.workDir);if(!J){r0("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){r0("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=WX(Z,this.opts.workDir,this.sessionId??void 0);if(!J){r0("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:E5(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)??x0(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"?x5($,this.opts.workDir):WX($,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:iL(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=Y8($.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=Y8($.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=jX($);for(let Y of Q){if(this.collabAgentSettled.has(Y))continue;if(this.collabAgentSettled.add(Y),!this.collabAgentNames.has(Y))this.collabAgentNames.set(Y,Y8(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:KX($.prompt),description:nL($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:aL($),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($)??Y8(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:KX(J.prompt)};this.emit("bg_task_started",X);let H={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",H)}if(Q==="running"||Q==="pendingInit"||Q==="interrupted"){let V={task_id:$,patch:{status:Q==="pendingInit"?"pending":Q==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",V);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Y={task_id:$,status:Q==="completed"?"completed":Q==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Y)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new VX("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=zX(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=V8($).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??zX(this.sessionId);if(!$){B(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Y=V8($).size;if(Y<=this.rolloutReadOffset)return;let V=Y-this.rolloutReadOffset;Z=Buffer.allocUnsafe(V);let X=NL($,"r"),H=0;try{while(H<V){let z=TL(X,Z,H,V-H,this.rolloutReadOffset+H);if(z===0)break;H+=z}}finally{UL(X)}Z=Z.subarray(0,H),this.rolloutReadOffset+=H}catch(Y){B(`codex-process: image generation rollout read failed ${$}: ${Y instanceof Error?Y.message:Y}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Q=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
81
81
  `)?"":Q.pop()??"";for(let Y of Q){if(!Y.trim())continue;let V;try{V=JSON.parse(Y)}catch(z){B(`codex-process: image generation rollout JSON parse failed ${$}: ${z instanceof Error?z.message:z}`);continue}let X=V?.payload,H=X?.type;if(H!=="image_generation_end"&&H!=="image_generation_call")continue;this.emitRolloutImageGeneration(X)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=BX($,this.sessionId??void 0);if(!J)return;let Q=$?.status==="failed",Y=$?.status==="generating"&&YX(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:E5({...$,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:r0("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=kL){let Q=++this.requestCounter;return new Promise((Y,V)=>{let X=setTimeout(()=>{let z=this.pending.get(Q);if(!z)return;this.pending.delete(Q),z.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),H={resolve:Y,reject:V,method:$,timeout:X};this.pending.set(Q,H),this.write({id:Q,method:$,params:Z},(z)=>{if(this.pending.get(Q)!==H)return;this.pending.delete(Q),clearTimeout(X),V(Error(`codex app-server ${$} request write failed (id=${Q}): ${z.message}`,{cause:z}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,result:Z})}respondError($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{B(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Q;if($.kind==="resume")J="thread/resume",Q=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Q=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Q=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Y=Q?.thread;if(typeof Y?.id!=="string"||!Y.id)throw Error(`codex app-server ${J} returned no thread.id`);let V=typeof Y.cwd==="string"?Y.cwd:typeof Q?.cwd==="string"?Q.cwd:null;if(V!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${V??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Y.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Y.id}`);if($.kind==="resume"&&Y.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Y.id}, expected ${$.source.sessionId}`);let X=typeof Y.path==="string"&&Y.path?Y.path:null;if(!X||!YX(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(W$(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},wL))?.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=V8(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(U0($,"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(" ")+`
82
+ `,(Q)=>{if(Q)J(Q)}),!0}catch(Q){return J(Q)}}request($,Z,J=kL){let Q=++this.requestCounter;return new Promise((Y,V)=>{let X=setTimeout(()=>{let z=this.pending.get(Q);if(!z)return;this.pending.delete(Q),z.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Q})`))},Math.max(0,J)),H={resolve:Y,reject:V,method:$,timeout:X};this.pending.set(Q,H),this.write({id:Q,method:$,params:Z},(z)=>{if(this.pending.get(Q)!==H)return;this.pending.delete(Q),clearTimeout(X),V(Error(`codex app-server ${$} request write failed (id=${Q}): ${z.message}`,{cause:z}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,result:Z})}respondError($,Z){let J=String($),Q=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Q?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{B(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Q;if($.kind==="resume")J="thread/resume",Q=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Q=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Q=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Y=Q?.thread;if(typeof Y?.id!=="string"||!Y.id)throw Error(`codex app-server ${J} returned no thread.id`);let V=typeof Y.cwd==="string"?Y.cwd:typeof Q?.cwd==="string"?Q.cwd:null;if(V!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${V??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Y.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Y.id}`);if($.kind==="resume"&&Y.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Y.id}, expected ${$.source.sessionId}`);let X=typeof Y.path==="string"&&Y.path?Y.path:null;if(!X||!YX(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(W$(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},wL))?.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=V8(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(" ")+`
83
83
 
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:mL(V.supportedReasoningEfforts),defaultReasoningEffort:W$(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(u2("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 d2&&$.method==="turn/start"&&HX($.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 d2&&$.method==="turn/start"&&Z.inputText!==void 0&&(Q8($.serverData)||Q8({message:$.serverMessage}))?{codexQuotaFailure:{accepted:!1,rejectedInput:Z.inputText}}:{}})}recordTurnStarted($,Z,J,Q){let Y=typeof $?.id==="string"&&$.id?$.id:null;if(!Y)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Y))return;let V=Q??this.turnStartOwner;if(V?.interrupted){if(this.rememberFinishedTurn(Y),this.turnStartOwner===V)this.turnStartOwner=null;this.interruptTurn(Y);return}this.confirmTurnStart(Y,Q);let X=this.currentTurnId!==Y;if(this.currentTurnId=Y,!X)return;let H=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let z={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",z)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...H?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Q=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Q?.turn,this.sessionId,"turn/start response",J)}catch(Q){if(!this.ownsTurnStartFailure(J)){B(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Q}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>B(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Q=Math.min(yL*2**Math.min(J-1,4),vL),Y=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Q,message:$};this.turnRetry=V,B(`codex-process: model capacity retry #${J} in ${Q}ms: ${$}`);let X=setTimeout(()=>{if(this.capacityRetryTimer!==X)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Y!==(this.turnStartGeneration??0))return;if(this.turnRetry={...V,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Y!==(this.turnStartGeneration??0))return;let H=this.beginTurnStart(Z);this.startTurn(Z,H).catch((z)=>this.failTurnStart(z,H))},Q);return this.capacityRetryTimer=X,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Q=this.serverRequests.get(String($));if(!Q){B(`codex-process: permission response for unknown request ${$}`);return}let Y=Z==="allow";switch(Q.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/permissions/requestApproval":if(Y)this.respond($,{permissions:Q.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Y){this.respondError($,J?.denyMessage??"denied by user");return}let V=J?.updatedInput?.answers??{},X={};for(let H of Q.params?.questions??[]){let z=V[H.question]??V[H.id];if(z!==void 0)X[H.id]={answers:[String(z)]}}this.respond($,{answers:X});return}default:r0("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Q.method,params:Q.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,B(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(B(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Q=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw B(`codex-process: kill failed: ${Q.message}`),Q}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!1),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}}});function s($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function i1($,Z){let J=$.agent==="claude"?s4.filter((Y)=>Y!=="default"):$.agent==="codex"?[...Q9]:["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 X8($,Z){let J=$.modelSelection,Q=new Set(s(Z.hidden_models)),Y=[...new Set([...s(Z.custom_models),...J?[]:s(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},X=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.modelIds=[];try{await X()}catch(W){throw $.models=[],$.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W instanceof Error?W.message:String(W)},W}if($.modelCatalogState?.status!=="ready")return;let H=$.models,z=(J?V.availableModels:H).map((W)=>({...W,origin:W.origin??"upstream"}));for(let W of Y){if(z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))continue;z.push({model:W,display:W,origin:"custom",...i1($,Z)})}V.availableModels=z;let G=J?H.map((W)=>z.find((K)=>K.model===W.model)??{...W,origin:"upstream"}):z;$.models=[...G.filter((W)=>W.origin==="custom"||!Q.has(W.model)),...z.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],V.modelIds=$.models.map((W)=>W.model)},$}var o$=R(()=>{B0();j1()});import{createHash as oL}from"node:crypto";class $${now;entries=new Map;constructor($=()=>Date.now()){this.now=$}read($,Z){let J=this.entries.get($);if(J?.pending)return J.pending;if(J&&this.now()<J.retryAt)return J.failed?Promise.reject(J.error):Promise.resolve(J.value);J??={failed:!1,failures:0,retryAt:0},this.entries.set($,J);let Q=J,Y=(X,H=0)=>{Q.failures=X?0:Q.failures+1;let z=X?H8:Math.min(sL,H8*2**Math.min(Q.failures-1,3));Q.retryAt=this.now()+Math.max(z,Number.isFinite(H)?H:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Q){if(Q.value=X,X.state==="ok")Q.successfulValue=X;else if(X.state==="no_credentials"||X.state==="auth_failed"||e0(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,e0(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")&&!e0(J.reason)?Q:J}).catch((J)=>{let Q=this.peekSuccessful($);if(Q&&tL(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()+H8})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function tL($){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 e0($){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 K$($,Z,J){return oL("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function b$($,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 n2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var H8=60000,sL=300000;var s$=()=>{};function z8($,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():"";qX.set($,{revision:J,email:Q||null,...!Q?{error:Z?.type==="chatgpt"?"原生账号未提供邮箱":"该账号未登录 ChatGPT"}:{}})}function LX($){let Z=qX.get($);return Z?.revision===v.revision($)?Z:void 0}var qX;var G8=R(()=>{D0();qX=new Map});import{spawn as rL}from"cross-spawn";import{EventEmitter as eL}from"node:events";import{StringDecoder as $P}from"node:string_decoder";import{createHash as ZP}from"node:crypto";function DX($,Z){if(Z.state==="ok"){a2.set($,Z),V9.set($,Z);return}if(Z.state==="no_credentials"||Z.state==="auth_failed")a2.set($,Z),V9.delete($);else if(!V9.has($))a2.set($,Z)}function FX($,Z,J=(Q)=>new t$({accountId:Q})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Q=W8.get($);if(Q)return Q.key===Z?Q.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Y=Promise.resolve().then(async()=>{let V=J($),X,H;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");L1($);let G;try{G=await P1(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{L1($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(G?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(G)};请用 codex-accounts 核对后再操作`);let W=q1.get($),K;try{K=await C5.read($,async()=>OX(await xX(()=>V.request("account/rateLimits/read",{})),z.planType))}catch(_){K={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(q1.get($)!==W)K={state:"auth_failed"};else DX($,K);if(K.state!=="ok")B(`codex-reset: ${$} quota refresh failed: ${K.state==="network"?K.reason:K.state}`);X={outcome:G.outcome,usage:K}}catch(z){H=z,B(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let G=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(B(`codex-reset: ${$}: ${G}`),X)X.cleanupError=G;else throw AggregateError([H,z],`${String(H)};${G}`)}if(!X)throw H;return X}).finally(()=>{if(W8.get($)?.promise===Y)W8.delete($)});return W8.set($,{key:Z,promise:Y}),Y}function UX($,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 JP($){return typeof $==="number"&&Number.isFinite($)&&$>=0&&$<=100?$:null}function K8($){if(!$)return null;return{percent:JP($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function QP($){let Z=K8($?.primary),J=K8($?.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 YP($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Q=[];for(let[Y,V]of J){let{fiveHour:X,weekly:H}=QP(V);if(!X&&!H)continue;Q.push({limitId:Y,limitName:V?.limitName??null,fiveHour:X,weekly:H,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function VP($){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 MX($,Z=c){let J=VP($),Q=a2.get(Z),Y=Q?.state==="ok"?Q.buckets??[]:[],V=Y.filter((X)=>PX(X.fiveHour,K8($?.primary))&&PX(X.weekly,K8($?.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 PX($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function XP($){let Z=v.revision($),J=new t$({accountId:$});try{await J.initialize("lodestar-usage");let Y=(await UX(J.request("account/read",{}),S5))?.account;if(z8($,Y,Z),!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let V,X=await xX(()=>{return V=Date.now(),J.request("account/rateLimits/read",{})});return OX(X,Y.planType,V)}catch(Q){if(B(`usage: codex app-server usage failed: ${Q?.message??Q}`),e0(Q))return{state:"auth_failed"};if(n2(Q))return{state:"rate_limited"};return{state:"network",reason:Q?.message??String(Q)}}finally{await J.close()}}function OX($,Z,J){let{buckets:Q,defaultLimitId:Y}=YP($),V=Q.find((H)=>H.limitId===Y)??Q[0];if(!V)return{state:"network",reason:"empty rate limit response"};let X=Z??$?.rateLimits?.planType??void 0;return V.fiveHour=N5(X,V.fiveHour),{state:"ok",subscriptionType:X,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:ZP("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:V.rateLimitReachedType,spendControlReached:V.spendControlReached,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 n1($=c){return a2.get($)??null}function X9($=c){return V9.get($)??null}function b5($=c){let Z=q1.get($)??0;return{accountId:$,read:()=>(q1.get($)??0)===Z?X9($):null}}function AX($=c){let Z=q1.get($)??0;return C5.read($,async()=>{try{return await XP($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(e0(J))return{state:"auth_failed"};if(n2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((q1.get($)??0)!==Z)return{state:"auth_failed"};return DX($,J),J})}async function NX($=c){return n1($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}}function TX(){return RX}function L1($){RX++,q1.set($,(q1.get($)??0)+1),a2.delete($),V9.delete($),C5.invalidate($)}function xX($){return P1($,"额度查询",{retryRateLimits:!1})}async function P1($,Z="额度查询",J={}){let Q=[1000,4000];for(let Y=0;;Y++)try{return await UX($(),S5)}catch(V){let X=V instanceof Error?V.message:String(V);if(e0(V))throw V;if(n2(V))throw V;if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(X))throw V;if(Y>=Q.length)throw Error(`Codex ${Z}失败(已尝试 ${Y+1} 次):${X}`,{cause:V});B(`usage: ${Z} retry ${Y+1}/${Q.length} in ${Q[Y]}ms: ${X}`),await new Promise((z)=>setTimeout(z,Q[Y]))}}var S5=1e4,a2,V9,C5,W8,t$,q1,RX=0;var U$=R(()=>{j1();I();f0();D0();s$();G8();a2=new Map,V9=new Map,C5=new $$;W8=new Map;t$=class t$ extends eL{proc;buf="";decoder=new $P("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??c;this.proc=rL($.bin??J9(),["app-server","--listen","stdio://",...$.args??v.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??v.env(Z,{...process.env,...p.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}`))}),K1(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
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:mL(V.supportedReasoningEfforts),defaultReasoningEffort:W$(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(u2("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 d2&&$.method==="turn/start"&&HX($.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 d2&&$.method==="turn/start"&&Z.inputText!==void 0&&(Q8($.serverData)||Q8({message:$.serverMessage}))?{codexQuotaFailure:{accepted:!1,rejectedInput:Z.inputText}}:{}})}recordTurnStarted($,Z,J,Q){let Y=typeof $?.id==="string"&&$.id?$.id:null;if(!Y)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Y))return;let V=Q??this.turnStartOwner;if(V?.interrupted){if(this.rememberFinishedTurn(Y),this.turnStartOwner===V)this.turnStartOwner=null;this.interruptTurn(Y);return}this.confirmTurnStart(Y,Q);let X=this.currentTurnId!==Y;if(this.currentTurnId=Y,!X)return;let H=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let z={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",z)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Y,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...H?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Q=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Q?.turn,this.sessionId,"turn/start response",J)}catch(Q){if(!this.ownsTurnStartFailure(J)){B(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Q}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>B(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Q=Math.min(yL*2**Math.min(J-1,4),vL),Y=this.turnStartGeneration??0,V={phase:"waiting",attempt:J,delayMs:Q,message:$};this.turnRetry=V,B(`codex-process: model capacity retry #${J} in ${Q}ms: ${$}`);let X=setTimeout(()=>{if(this.capacityRetryTimer!==X)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Y!==(this.turnStartGeneration??0))return;if(this.turnRetry={...V,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Y!==(this.turnStartGeneration??0))return;let H=this.beginTurnStart(Z);this.startTurn(Z,H).catch((z)=>this.failTurnStart(z,H))},Q);return this.capacityRetryTimer=X,this.emit("turn_retry",V),!0}sendPermissionResponse($,Z,J){let Q=this.serverRequests.get(String($));if(!Q){B(`codex-process: permission response for unknown request ${$}`);return}let Y=Z==="allow";switch(Q.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Y?"accept":"decline"});return;case"item/permissions/requestApproval":if(Y)this.respond($,{permissions:Q.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Y){this.respondError($,J?.denyMessage??"denied by user");return}let V=J?.updatedInput?.answers??{},X={};for(let H of Q.params?.questions??[]){let z=V[H.question]??V[H.id];if(z!==void 0)X[H.id]={answers:[String(z)]}}this.respond($,{answers:X});return}default:r0("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Q.method,params:Q.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,B(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(B(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Q=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw B(`codex-process: kill failed: ${Q.message}`),Q}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!1),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}}});function s($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function i1($,Z){let J=$.agent==="claude"?s4.filter((Y)=>Y!=="default"):$.agent==="codex"?[...Q9]:["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 X8($,Z){let J=$.modelSelection,Q=new Set(s(Z.hidden_models)),Y=[...new Set([...s(Z.custom_models),...J?[]:s(Z.models)])],V=$.modelSelection=J??{mode:"catalog",modelIds:[],availableModels:[]},X=$.refreshModels.bind($);return $.refreshModels=async()=>{if($.models=[],V.availableModels=[],!J)V.modelIds=[];try{await X()}catch(W){throw $.models=[],$.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W instanceof Error?W.message:String(W)},W}if($.modelCatalogState?.status!=="ready")return;let H=$.models,z=(J?V.availableModels:H).map((W)=>({...W,origin:W.origin??"upstream"}));for(let W of Y){if(z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))continue;z.push({model:W,display:W,origin:"custom",...i1($,Z)})}V.availableModels=z;let G=J?H.map((W)=>z.find((K)=>K.model===W.model)??{...W,origin:"upstream"}):z;$.models=[...G.filter((W)=>W.origin==="custom"||!Q.has(W.model)),...z.filter((W)=>W.origin==="custom"&&!G.some((K)=>K.model===W.model))],V.modelIds=$.models.map((W)=>W.model)},$}var o$=R(()=>{B0();j1()});import{createHash as oL}from"node:crypto";class $${now;entries=new Map;constructor($=()=>Date.now()){this.now=$}read($,Z){let J=this.entries.get($);if(J?.pending)return J.pending;if(J&&this.now()<J.retryAt)return J.failed?Promise.reject(J.error):Promise.resolve(J.value);J??={failed:!1,failures:0,retryAt:0},this.entries.set($,J);let Q=J,Y=(X,H=0)=>{Q.failures=X?0:Q.failures+1;let z=X?H8:Math.min(sL,H8*2**Math.min(Q.failures-1,3));Q.retryAt=this.now()+Math.max(z,Number.isFinite(H)?H:0)},V=Promise.resolve().then(Z).then((X)=>{if(this.entries.get($)===Q){if(Q.value=X,X.state==="ok")Q.successfulValue=X;else if(X.state==="no_credentials"||X.state==="auth_failed"||e0(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,e0(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")&&!e0(J.reason)?Q:J}).catch((J)=>{let Q=this.peekSuccessful($);if(Q&&tL(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()+H8})}invalidate($){this.entries.delete($)}clear(){this.entries.clear()}}function tL($){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 e0($){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 K$($,Z,J){return oL("sha256").update(JSON.stringify([$,Z,J])).digest("hex")}function b$($,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 n2($){let Z=$ instanceof Error?$.message:String($);return/\b429\b|too many requests|\brate[ _-]?limit(?:ed|[ _-](?:exceeded|reached))\b/i.test(Z)}var H8=60000,sL=300000;var s$=()=>{};function z8($,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():"";qX.set($,{revision:J,email:Q||null,...!Q?{error:Z?.type==="chatgpt"?"原生账号未提供邮箱":"该账号未登录 ChatGPT"}:{}})}function LX($){let Z=qX.get($);return Z?.revision===v.revision($)?Z:void 0}var qX;var G8=R(()=>{D0();qX=new Map});import{spawn as rL}from"cross-spawn";import{EventEmitter as eL}from"node:events";import{StringDecoder as $P}from"node:string_decoder";import{createHash as ZP}from"node:crypto";function DX($,Z){if(Z.state==="ok"){a2.set($,Z),V9.set($,Z);return}if(Z.state==="no_credentials"||Z.state==="auth_failed")a2.set($,Z),V9.delete($);else if(!V9.has($))a2.set($,Z)}function FX($,Z,J=(Q)=>new t$({accountId:Q})){if(!$||!Z.trim())return Promise.reject(Error("重置卡请求缺少账号或幂等标识"));let Q=W8.get($);if(Q)return Q.key===Z?Q.promise:Promise.reject(Error("该账号正在使用重置卡,请等待结果后再操作"));let Y=Promise.resolve().then(async()=>{let V=J($),X,H;try{await V.initialize("lodestar-codex-reset");let z=(await V.request("account/read",{}))?.account;if(!z||z.type!=="chatgpt")throw Error("该账号未登录 ChatGPT 订阅,不能使用重置卡");L1($);let G;try{G=await P1(()=>V.request("account/rateLimitResetCredit/consume",{idempotencyKey:Z}),"重置卡请求")}catch(_){throw Error(`重置卡请求未确认结果:${_ instanceof Error?_.message:String(_)};请用 codex-accounts 核对额度与重置卡次数`,{cause:_})}finally{L1($)}if(!["reset","alreadyRedeemed","nothingToReset","noCredit"].includes(G?.outcome))throw Error(`Codex 重置卡返回未知结果:${JSON.stringify(G)};请用 codex-accounts 核对后再操作`);let W=q1.get($),K;try{K=await C5.read($,async()=>OX(await xX(()=>V.request("account/rateLimits/read",{})),z.planType))}catch(_){K={state:"network",reason:_ instanceof Error?_.message:String(_)}}if(q1.get($)!==W)K={state:"auth_failed"};else DX($,K);if(K.state!=="ok")B(`codex-reset: ${$} quota refresh failed: ${K.state==="network"?K.reason:K.state}`);X={outcome:G.outcome,usage:K}}catch(z){H=z,B(`codex-reset: ${$}: ${z}`)}try{await V.close()}catch(z){let G=`控制连接关闭失败:${z instanceof Error?z.message:String(z)}`;if(B(`codex-reset: ${$}: ${G}`),X)X.cleanupError=G;else throw AggregateError([H,z],`${String(H)};${G}`)}if(!X)throw H;return X}).finally(()=>{if(W8.get($)?.promise===Y)W8.delete($)});return W8.set($,{key:Z,promise:Y}),Y}function MX($,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 JP($){return typeof $==="number"&&Number.isFinite($)&&$>=0&&$<=100?$:null}function K8($){if(!$)return null;return{percent:JP($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function QP($){let Z=K8($?.primary),J=K8($?.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 YP($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Q=[];for(let[Y,V]of J){let{fiveHour:X,weekly:H}=QP(V);if(!X&&!H)continue;Q.push({limitId:Y,limitName:V?.limitName??null,fiveHour:X,weekly:H,normalModelSlug:V?.normalModelSlug??null,rateLimitReachedType:V?.rateLimitReachedType??null,spendControlReached:V?.spendControlReached??null})}return{buckets:Q,defaultLimitId:$?.rateLimits?.limitId??void 0}}function VP($){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 UX($,Z=c){let J=VP($),Q=a2.get(Z),Y=Q?.state==="ok"?Q.buckets??[]:[],V=Y.filter((X)=>PX(X.fiveHour,K8($?.primary))&&PX(X.weekly,K8($?.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 PX($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function XP($){let Z=v.revision($),J=new t$({accountId:$});try{await J.initialize("lodestar-usage");let Y=(await MX(J.request("account/read",{}),S5))?.account;if(z8($,Y,Z),!Y)return{state:"no_credentials"};if(Y.type!=="chatgpt")return{state:"auth_failed"};let V,X=await xX(()=>{return V=Date.now(),J.request("account/rateLimits/read",{})});return OX(X,Y.planType,V)}catch(Q){if(B(`usage: codex app-server usage failed: ${Q?.message??Q}`),e0(Q))return{state:"auth_failed"};if(n2(Q))return{state:"rate_limited"};return{state:"network",reason:Q?.message??String(Q)}}finally{await J.close()}}function OX($,Z,J){let{buckets:Q,defaultLimitId:Y}=YP($),V=Q.find((H)=>H.limitId===Y)??Q[0];if(!V)return{state:"network",reason:"empty rate limit response"};let X=Z??$?.rateLimits?.planType??void 0;return V.fiveHour=N5(X,V.fiveHour),{state:"ok",subscriptionType:X,...typeof $?.accountId==="string"&&$.accountId?{accountFingerprint:ZP("sha256").update($.accountId).digest("hex")}:{},...typeof $?.ordinaryUsageAllowed==="boolean"?{ordinaryUsageAllowed:$.ordinaryUsageAllowed}:{},rateLimitReachedType:V.rateLimitReachedType,spendControlReached:V.spendControlReached,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 n1($=c){return a2.get($)??null}function X9($=c){return V9.get($)??null}function b5($=c){let Z=q1.get($)??0;return{accountId:$,read:()=>(q1.get($)??0)===Z?X9($):null}}function AX($=c){let Z=q1.get($)??0;return C5.read($,async()=>{try{return await XP($)}catch(J){throw B(`usage: ${$} fetch failed: ${J}`),J}}).catch((J)=>{if(e0(J))return{state:"auth_failed"};if(n2(J))return{state:"rate_limited"};return{state:"network",reason:String(J)}}).then((J)=>{if((q1.get($)??0)!==Z)return{state:"auth_failed"};return DX($,J),J})}async function NX($=c){return n1($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}}function TX(){return RX}function L1($){RX++,q1.set($,(q1.get($)??0)+1),a2.delete($),V9.delete($),C5.invalidate($)}function xX($){return P1($,"额度查询",{retryRateLimits:!1})}async function P1($,Z="额度查询",J={}){let Q=[1000,4000];for(let Y=0;;Y++)try{return await MX($(),S5)}catch(V){let X=V instanceof Error?V.message:String(V);if(e0(V))throw V;if(n2(V))throw V;if(!/error sending request|timed? ?out|timeout|ECONNRESET|ETIMEDOUT|EAI_AGAIN|connection (?:reset|closed)|\b(?:429|502|503|504)\b/i.test(X))throw V;if(Y>=Q.length)throw Error(`Codex ${Z}失败(已尝试 ${Y+1} 次):${X}`,{cause:V});B(`usage: ${Z} retry ${Y+1}/${Q.length} in ${Q[Y]}ms: ${X}`),await new Promise((z)=>setTimeout(z,Q[Y]))}}var S5=1e4,a2,V9,C5,W8,t$,q1,RX=0;var M$=R(()=>{j1();I();f0();D0();s$();G8();a2=new Map,V9=new Map,C5=new $$;W8=new Map;t$=class t$ extends eL{proc;buf="";decoder=new $P("utf8");nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor($={}){super();let Z=$.accountId??c;this.proc=rL($.bin??J9(),["app-server","--listen","stdio://",...$.args??v.cliArgs(Z)],{stdio:["pipe","pipe","pipe"],shell:!1,cwd:$.cwd,env:$.env??v.env(Z,{...process.env,...p.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}`))}),K1(this,Z)}onStdout($){this.buf+=this.decoder.write($);let Z;while((Z=this.buf.indexOf(`
85
85
  `))>=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
86
  `);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
87
  `,(Q)=>Q?J(Q):Z())})}isAlive(){return this.alive}request($,Z,J=S5){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
88
  `,(H)=>{if(!H)return;let z=this.pending.get(Q);if(!z)return;this.pending.delete(Q),clearTimeout(z.timer),z.reject(Error(`codex app-server write failed for ${$}: ${H.message}`))})}catch(H){this.pending.delete(Q),clearTimeout(X),V(H instanceof Error?H:Error(String(H)))}})}async close($=2000){if(!this.alive)return;if(this.proc.exitCode!==null||this.proc.signalCode!==null){if(!await this.waitForExit($))throw Error("codex app-server stdio did not close after exit");return}if(!this.proc.kill("SIGTERM"))throw Error("codex app-server rejected SIGTERM");if(await this.waitForExit($))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await this.waitForExit($))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}async waitForExit($){let Z;try{return await Promise.race([this.exitPromise.then(()=>!0),new Promise((J)=>{Z=setTimeout(()=>J(!1),$)})])}finally{if(Z!==void 0)clearTimeout(Z)}}};q1=new Map});var kX={};d$(kX,{waitForTokenSourceModelRefresh:()=>zP,tokenSourceRuntimeModels:()=>D1,tokenSourceRuntimeModel:()=>k$,tokenSourceRegistryRevision:()=>w5,tokenSourceProcessRevision:()=>s2,tokenSourceFactories:()=>a1,setDefaultTokenSource:()=>f5,scrubDshEnv:()=>H9,scrubAnthropicEnv:()=>l0,resetTokenSourceRegistry:()=>h5,registerTokenSourceFactory:()=>L0,registerTokenSource:()=>y5,refreshAllTokenSourceModels:()=>HP,pendingTokenSourceModelRefresh:()=>bX,listTokenSourcesByAgent:()=>SX,listTokenSources:()=>u0,listTokenSourceAccounts:()=>CX,listEnabledTokenSourcesByAgent:()=>v5,getTokenSourceForAccount:()=>G0,getTokenSource:()=>E0,ANTHROPIC_ENV_KEYS:()=>_8});function l0($){let Z={...$};for(let J of _8)delete Z[J];return delete Z.LODESTAR_PACKY_API_KEY,Z}function H9($){let Z=l0($);for(let J of Object.keys(Z))if(/^(DSH_|DEEPSEEK_|LODESTAR_DSH_|ZAI_|ZHIPU_)/.test(J))delete Z[J];return Z}function D1($){return $.modelSelection?[...$.models,...$.modelSelection.availableModels.filter((Z)=>!$.models.some((J)=>J.model===Z.model))]:$.models}function k$($,Z){let J=(Q)=>$.agent==="claude"?Q?.replace(/\[1m\]$/,""):Q;return D1($).find((Q)=>J(Q.model)===J(Z))}function s2($,Z){let J=$?.spawnRevision??null,Q=$?.modelEnvironmentRevision?.(Z??$.defaultModel);return Q===void 0?J:JSON.stringify([J,Q])}function L0($){EX.set($.kind,$)}function a1(){return[...EX.values()]}function w5(){return k5}function y5($,Z){if(z9.set($.id,$),Z?.default||B8===null)B8=$.id}function E0($){return $?z9.get($):void 0}function G0($,Z="default"){let J=E0($);return J?.forAccount?J.forAccount(Z):J}function u0(){return[...z9.values()]}function SX($){return u0().filter((Z)=>Z.agent===$)}function v5($){return SX($).filter((Z)=>Z.enabled)}function f5($){if(z9.has($))B8=$}function h5(){z9.clear(),B8=null,k5++}function HP(){let $=k5;if(o2?.generation===$)return o2.promise;let Z=Promise.allSettled(CX().map(async(J)=>{await J.refreshModels(),B(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(o2?.promise===Z)o2=null});return o2={generation:$,promise:Z},Z}function CX(){return u0().flatMap(($)=>$.forAccount?v.list().map((Z)=>$.forAccount(Z.id)):[$])}function bX(){return o2?.promise??null}async function zP(){let $;while($=bX())await $}var _8,EX,z9,B8=null,k5=0,o2=null;var Q0=R(()=>{I();D0();_8=["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;z9=new Map});function F1($){return $.startsWith("claude:")?$:`claude:${$}`}function G9($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(p.claude.models,Z))return p.claude.models[Z]?.model?.trim()||"opus";return Z}var I5=R(()=>{f0()});import{existsSync as GP,readFileSync as WP}from"node:fs";function g5(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:iY}function K9(){if(W9!==null)return W9;try{W9=GP(g5())?JSON.parse(WP(g5(),"utf8")):{}}catch($){B(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),W9={}}return W9??{}}function BP(){try{o(g5(),K9())}catch($){B(`context-window-observe: cache write MISS (${$?.message??$})`)}}function m5($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function wX($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Q=m5($,Z),Y=K9()[Q];if(Y===J)return;K9()[Q]=J,BP(),B(`context-window-observe: ${Q} → ${J} (prev ${Y??"-"})`)}function j8($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=K9()[m5($,Z)];return J!=null&&J<KP?Z:`${Z}[1m]`}function t2($,Z){return K9()[m5($,Z)]}var KP=1e6,W9=null;var B9=R(()=>{V0();I();v0()});var i5={};d$(i5,{toolsFromProfile:()=>nX,settingSourcesFromProfile:()=>iX,resolveClaudeExecutableConfig:()=>d5,resetClaudeContextWindowCache:()=>DP,readProjectMcpServers:()=>aX,readLastCallUsageFromTranscript:()=>lX,claudeTranscriptPath:()=>D8,claudeTranscriptDir:()=>P8,claudeManagedSkillOptions:()=>pX,buildClaudeSpawnPath:()=>cX,assertClaudeCodeAvailable:()=>u5,ClaudeAgentProcess:()=>F8,CLAUDE_PERMISSION_MODE:()=>dX});import{existsSync as IX,readFileSync as gX}from"node:fs";import{homedir as L8}from"node:os";import{spawn as _P}from"cross-spawn";import{delimiter as yX,join as o1}from"node:path";import{EventEmitter as jP}from"node:events";function pX($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function qP($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function LP($){let Z=_P($.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 u5(){d5(),J5("claude","@anthropic-ai/claude-agent-sdk")}function d5($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?p.claude.bin:$.configuredBin;if(J){if(!($.exists??IX)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&qP(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:LP,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}return{description:"sdk-default"}}function cX(){if(process.platform==="win32")return process.env.PATH??"";let $=[o1(L8(),".local","npm-global","bin"),o1(L8(),".local","bin"),o1(L8(),".bun","bin"),...(process.env.PATH??"").split(yX),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(yX)}function PP($){let Z=c2($);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 vX($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function P8($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||o1(L8(),".claude");return o1(J,"projects",Z)}function D8($,Z){return o1(P8($),`${Z}.jsonl`)}function lX($){let Z;try{Z=gX($,"utf8")}catch{return null}let J=Z.split(`
89
- `);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 fX($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function DP(){c5.clear()}function FP($){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)+r2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+r2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+r2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+r2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+r2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=r2(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 q8($){return{...$}}function p5($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function UP($,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 r2($){return typeof $==="number"&&Number.isFinite($)?$:0}function uX($){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(`
90
- `);return $==null?"":JSON.stringify($,null,2)}function MP($){let Z=uX($);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(`
89
+ `);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 fX($,Z){let J=Z?.trim()||"no-source",Q=$&&$.trim()?$:"claude:default";return`${J}:${Q}`}function DP(){c5.clear()}function FP($){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)+r2(V.inputTokens??V.input_tokens),Z.output_tokens=(Z.output_tokens??0)+r2(V.outputTokens??V.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+r2(V.reasoningOutputTokens??V.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+r2(V.cacheReadInputTokens??V.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+r2(V.cacheCreationInputTokens??V.cache_creation_input_tokens);let X=r2(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 q8($){return{...$}}function p5($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function MP($,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 r2($){return typeof $==="number"&&Number.isFinite($)?$:0}function uX($){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(`
90
+ `);return $==null?"":JSON.stringify($,null,2)}function UP($){let Z=uX($);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(`
91
91
  `)}}catch{}return Z}function OP($){return`server_tool:${$}`}function AP($){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 NP($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function RP($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[B1];return{id:F1($.value),model:F1($.value),displayName:$.displayName||F1($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(B1)?B1:Z[0]}}function iX($){if(!$?.settingSources)return[...hX];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...hX]}function nX($){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 aX($){let Z=o1($,".mcp.json"),J;try{J=gX(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 TP($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Q)=>xP(Q)).filter((Q)=>Q!==null)}function xP($){let Z=$&&typeof $==="object"?$:{question:$},J=l5(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Q=EP(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 EP($){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=l5(Q.label,Q.value,Q.text,Q.title);if(!Y?.trim())continue;let V=l5(Q.description,Q.detail,Q.preview);Z.push(V?{label:Y,description:V}:{label:Y})}return Z}function l5(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var mX,c5,dX="default",hX,F8;var e2=R(()=>{h2();f0();I();B0();I5();B9();mX=class mX{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($))}};c5=new Map;hX=["project","local"];F8=class F8 extends jP{provider="claude";tokenSourceId;opts;input=new mX;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?F1($.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 $=G9(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??iX(Z),Q=pX(J,this.opts.managedSkillPluginPath),Y=nX(Z),V=Z?.strictMcp===!0,X=Z?.loadProjectMcp!==!1?aX(this.opts.workDir):void 0;try{let H=d5(),{query:z}=await xV();if(!this.alive||this.abortController.signal.aborted)return;let G={...process.env,PATH:cX(),...p.claude.env,...this.opts.hostEnv??{}},W=this.opts.transformEnv?this.opts.transformEnv(G):G;if(W.CLAUDE_CODE_ENABLE_TODO_TOOLS="1",this.opts.effort==="default")W.CLAUDE_CODE_EFFORT_LEVEL="unset";B(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${H.description}`),this.query=z({prompt:this.opts.validateAccount?this.validatedInput():this.input,options:{cwd:this.opts.workDir,abortController:this.abortController,...$?{model:$}:{},effort:this.opts.effort==="default"?"high":this.opts.effort,resume:this.opts.resumeSessionId,...this.opts.resumeSessionAt?{resumeSessionAt:this.opts.resumeSessionAt}:{},...this.opts.forkSession?{forkSession:!0}:{},...H.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:H.pathToClaudeCodeExecutable}:{},...H.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:H.spawnClaudeCodeProcess}:{},permissionMode:dX,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 _=K.trim();if(_)B(`claude-agent-process[stderr]: ${_}`)}}})}catch(H){let z=H instanceof Error?H:Error(String(H));this.initializationError=z,this.emit("error",z),this.finishExit(1,null);return}if(this.readLoop(this.query),this.opts.validateAccount)try{this.opts.validateAccount(await this.query.accountInfo())}catch(H){this.initializationError=H instanceof Error?H:Error(String(H)),this.emit("error",this.initializationError),await this.kill()}}sendUserText($,Z=[]){if(!this.alive){B("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).join(" ")+`
92
92
 
93
- `:"";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(RP)}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=G9($);if(!A0(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 p2(`模型设置未确认:${Q instanceof Error?Q.message:String(Q)}`,null,{cause:Q})}this.opts.model=$,this.lastModel=J?F1($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Q){throw new p2(`模型已切换为 ${$},但思考档位未确认:${Q instanceof Error?Q.message:String(Q)}`,$,{cause:Q})}this.opts.effort=Z,this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Q=()=>{this.off("context_compacted",Y),this.off("assistant_text",V),this.off("exit",X),this.off("error",H)},Y=()=>{if(J)return;J=!0,Q(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new l1)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},H=(z)=>{if(J)return;J=!0,Q(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Y),this.on("assistant_text",V),this.once("exit",X),this.once("error",H)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=TP(Z);if(Q.length===0)return B("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Y={...Z,questions:Q},V=`claude_perm_${++this.requestCounter}`,X=J.toolUseID||V,H={request_id:V,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},z=new Promise((G)=>{let W=(_)=>{J.signal.removeEventListener("abort",K),G(_)},K=()=>{if(!this.pendingPermissions.delete(V))return;W({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:W,request:H})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",H),z}async readLoop($){try{for await(let Z of $)this.handleMessage(Z);this.finishExit(null,null)}catch(Z){let J=Z instanceof Error?Z:Error(String(Z));if(this.expectedExit&&this.abortController.signal.aborted){B(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}B(`claude-agent-process: read loop failed: ${J.message}`),this.emit("error",J),this.finishExit(1,null)}}finishExit($,Z){if(!this.alive)return;this.alive=!1,this.turnActive=!1,this.denyPendingPermissions("claude process exited"),this.resolveExit(),B(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:B(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=F1($.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=F1(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=AP(Y.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(NP(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,OP(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,MP(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=uX(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
94
- `):"",H=V||X;this.emitToolResultOnce(Q.tool_use_id,H,Q.is_error===!0||Y?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=PP($.usage),J=$.modelUsage??$.model_usage,Q=FP(J);if(!Z&&!Q.usage)B(`claude-agent-process: result usage missing rootKeys=${p5($).join(",")||"-"} usageKeys=${p5($.usage).join(",")||"-"} modelUsageKeys=${p5(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=q8(Q.usage),this.lastTotalUsage=q8(Q.usage);else if(Z)this.cumulativeUsageFromResults=UP(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=q8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?q8(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let H=fX(this.opts.model,this.tokenSourceId);if(c5.set(H,Q.contextWindow),this.tokenSourceId)for(let[z,G]of Object.entries(J??{})){let W=G?.contextWindow;if(typeof W==="number"&&W>0)wX(this.tokenSourceId,z,W)}}this.lastContextWindow=c5.get(fX(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=D8(this.opts.workDir,this.sessionId??""),V=lX(Y);if(this.lastContextTokens=vX(V)??(IX(Y)?vX(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(`
95
- `):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 SP}from"node:os";function bP($,Z=CP){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 oX($){return typeof $==="string"&&kP.includes($)?$:null}async function U8($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (e2(),i5)),J=new Z({workDir:SP(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Q)=>B(`Claude model catalog MISS: ${Q.message}`));try{let Q=await bP(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 sX($="default"){let Z=v.revision($),J=new t$({accountId:$});try{await J.initialize("lodestar-models");let Q=await P1(()=>J.request("account/read",{refreshToken:!1}),"账号查询");if(z8($,Q?.account,Z),Q?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await P1(()=>J.request("model/list",{}),"模型查询");if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let V=Y.data,X=[];for(let H of V){if(!H||H.hidden||!H.id)continue;let z=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((W)=>oX(W?.reasoningEffort)).filter((W)=>W!==null);if(!z.length)continue;let G=oX(H.defaultReasoningEffort)??z[0];X.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:z,defaultEffort:G})}if(!X.length)throw Error("Codex model/list 未返回可用模型");return X}finally{await J.close()}}async function tX($,Z){return(await y2($,Z)).map((Q)=>({model:Q,display:Q,efforts:$4,defaultEffort:"max"}))}var CP=1e4,kP,$4;var Z4=R(()=>{d4();U$();I();G8();D0();kP=["none","minimal","low","medium","high","xhigh","max","ultra"];$4=["max","xhigh","high","medium","low"]});import{existsSync as wP}from"node:fs";import{join as yP}from"node:path";function rX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function _9($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(rX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(rX($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function eX($){return $===c||wP(yP(v.home($),"auth.json"))}var M8=R(()=>{f0();Q0();U$();Z4();I();D0();o$();L0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(Y)=>{let V=eX(Y),X=$.model?.trim()||void 0,H=$.effort?.trim()||void 0,z={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(z.enabled=eX(Y),!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{if(z.models=await sX(Y),H)for(let G of z.models)G.defaultEffort=H;if(!X)z.defaultModel=z.models[0]?.model??"";z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(B(`codex-sub ${Y} refreshModels MISS: ${G?.message??G}`),z.models=[],G?.code==="CODEX_AUTH_MISSING")z.enabled=!1;z.modelCatalogState={status:z.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let W=l0(G);return Object.assign(W,p.codex.env),v.env(Y,W)},resolveSpawnModel(G){return G},async readUsage(){return _9(await AX(Y))}};return z},Q=J(c);return Q.forAccount=(Y)=>{if(Y===c)return Q;let V=v.revision(Y),X=Z.get(Y);if(X?.revision===V)return X.source;let H=X8(J(Y),$);return Z.set(Y,{revision:V,source:H}),H},Q}})});function $H($,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([...s(J.custom_models),...Q?.mode==="catalog"||$.kind.startsWith("packy")?s(J.models):[]])],X=[...Y];for(let W of V)if(!X.some((K)=>K.model.toLowerCase()===W.toLowerCase())){let K=Z.modelSelection?.availableModels.find((_)=>_.model===W);X.push(K?{...K,efforts:[...K.efforts]}:{model:W,display:W,origin:"custom",...i1($,J)})}let H=new Set(s(J.hidden_models)),z=J.models!==void 0?s(J.models):Q?.modelIds.length?Q.modelIds:Z.modelSelection?.modelIds??[],G=Q?.mode==="allowlist"?z.map((W)=>{let K=$.agent==="claude"?W.replace(/\[1m\]$/,""):W,_=X.find((j)=>j.model===K)??Z.models.find((j)=>j.model===W);return _?{..._,model:W}:{model:W,display:W,efforts:[],defaultEffort:null,unavailableReason:"账号目录缓存未返回该模型"}}).filter((W)=>!!W):X.filter((W)=>W.origin==="custom"||!H.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 n5($,Z,J,Q,Y,V){let X=Y&&j9.get(Y),H=$(),z=H.kind==="codex-subscription"?`${J}:${v.revision(V??c)}`:J;if(X?.active()&&X.configuration===Q&&X.identity===z)return Y;if(X?.identity===z)$H(H,Y,Z);let G={...H},W=!0,K=X?.identity===z?X.snapshot():void 0,_=new Map,j=(D)=>{H=D;let{refreshModels:F,readUsage:U,forAccount:M,...O}=D;Object.assign(G,O)},L=new i3(`token-source ${G.id}${V?`/${V}`:""} models`,vP,async()=>{let D=O8.get(z);if(!D){let A;try{A=$()}catch(y){throw G.modelCatalogState={status:G.modelCatalogState?.status==="ready"?"ready":"failed",updatedAt:G.modelCatalogState?.updatedAt??null,error:y instanceof Error?y.message:String(y)},y}let T=Promise.resolve().then(()=>A.refreshModels()).then(()=>({source:A}),(y)=>({source:A,error:y})).finally(()=>{if(O8.get(z)?.promise===T)O8.delete(z)});D={configuration:Q,promise:T},O8.set(z,D)}let F=await D.promise,U=F.source,M=F.error;if(D.configuration!==Q){if(U=$(),F.source.modelCatalogState?.status==="ready")$H(U,F.source,Z);else if(U.modelCatalogState=F.source.modelCatalogState&&{...F.source.modelCatalogState},!F.source.enabled)U.enabled=!1}if(!W)return;if(M!==void 0&&!U.modelCatalogState?.error)U.modelCatalogState={status:"failed",updatedAt:Date.now(),error:M instanceof Error?M.message:String(M)};let O=U.modelCatalogState?.error;if(O&&e0(O)){if(K={state:"no_credentials",windows:[],reason:O},G.kind==="codex-subscription")L1(V??c)}if(U.modelCatalogState?.status==="failed"||M){let A=U.modelCatalogState?.error??(M instanceof Error?M.message:String(M));if(G.modelCatalogState?.status==="ready"&&!e0(A))G.modelCatalogState={...G.modelCatalogState,error:A};else j(U);throw M??Error(A)}j(U)},X?.identity===z?X.model.nextRefreshAt:0),q=new i3(`token-source ${G.id}${V?`/${V}`:""} usage`,fP,async()=>{let D;try{D=await H.readUsage()}catch(F){let U=F instanceof Error?F.message:String(F);if(W&&(K?.state!=="ok"||e0(U)))K={state:e0(U)?"no_credentials":"network",windows:[],reason:U};throw F}if(!W)return;if(K?.state!=="ok"||!["network","rate_limited"].includes(D.state)||e0(D.reason))K=D;if(D.state!=="ok"&&D.state!=="not_applicable"&&D.state!=="no_credentials")throw Object.assign(Error(D.reason??D.state),{retryAfterMs:D.retryAfterMs})},X?.identity===z?X.usage.nextRefreshAt:0);if(G.refreshModels=()=>L.refresh(),G.readUsage=async()=>!G.enabled?{state:"no_credentials",windows:[],reason:G.modelCatalogState?.error}:G.kind==="codex-subscription"?_9(n1(V)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}):K??{state:G.enabled?"network":"no_credentials",windows:[],reason:"额度缓存尚未就绪,后台刷新中"},H.forAccount)G.forAccount=(D)=>{if(D===c)return G;let F=v.revision(D),U=_.get(D);if(U?.revision===F)return U.source;if(U)q9(U.source);let M=X?.baseIdentity===J?X.children.get(D):void 0,O=n5(()=>$().forAccount(D),Z,J,Q,M?.revision===F?M.source:void 0,D);return _.set(D,{revision:F,source:O}),O};return j9.set(G,{baseIdentity:J,identity:z,configuration:Q,model:L,usage:q,children:_,snapshot:()=>K,active:()=>W,dispose(){W=!1,L.dispose(),q.dispose();for(let D of _.values())q9(D.source)}}),G}function q9($){j9.get($)?.dispose()}function ZH($,Z){let J=$&&j9.get($),Q=J?.children.get(Z);if(Q)q9(Q.source),J.children.delete(Z)}function JH($){return j9.get($)?.usage.refresh()??Promise.resolve()}var vP=300000,fP=60000,j9,O8;var A8=R(()=>{H5();D0();o$();U$();M8();s$();j9=new WeakMap,O8=new Map});function IP($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!hP.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 P9{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 QH($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class o5{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 a5($){if(Array.isArray($))return`[${$.map(a5).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)}:${a5(J)}`).join(",")}}`}function gP($){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${a5(V)}`}function mP($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${gP($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function pP(){return new Promise(($)=>setTimeout($,0))}function L9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function YH($){let Z=$.afterAck??pP,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=IP(Y);if(V)return $.responses.invalid(Y,V);let X=mP(Y),H=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],z=$.deduper.claimAll(H);if(z==="inflight")return $.responses.inflight(Y);if(z==="completed")return $.responses.completed(Y);let G=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(_){$.deduper.failAll(H),J(_);return}let W;try{W=await $.execute(Y)}catch(_){L9($.deduper,X,!0),await Q(()=>$.presentExecutionFailure(Y,_));return}await Q(async()=>{try{await $.present(Y,W)}catch(_){await $.presentPresentationFailure(Y,_)}});let K;try{K=$.completion(Y,W)}catch(_){L9($.deduper,X,!1),J(_);return}if(K){let _=K.then((j)=>{L9($.deduper,X,j==="complete")},(j)=>{L9($.deduper,X,!1),J(j)});$.track(_);return}L9($.deduper,X,$.businessSucceeded(Y,W))});if(!G.accepted)return $.deduper.failAll(H),$.responses.closed(Y);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Y)}}}var hP;var s5=R(()=>{hP=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 cP}from"node:async_hooks";class VH{actor=new P9;context=new cP;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 M$($,Z){return lP.run($,Z)}var lP;var t5=R(()=>{s5();lP=new VH});import{execFileSync as uP}from"node:child_process";import{existsSync as U1,readdirSync as dP,readFileSync as iP,realpathSync as R8,statSync as nP}from"node:fs";import{dirname as aP,join as HH,resolve as oP}from"node:path";async function T8($,Z){let J=R8($),Q=process.platform==="win32"?J.toLowerCase():J,Y=N8.get(Q)??Promise.resolve(),V,X=new Promise((z)=>{V=z}),H=Y.catch(()=>{}).then(()=>X);N8.set(Q,H),await Y.catch(()=>{});try{return await Z()}finally{if(V(),N8.get(Q)===H)N8.delete(Q)}}function s1($){let Z=$.trim();if(!sP.test(Z))return null;return Z}function x8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function Q4($,Z){return`${$}[${Z}]`}function zH($){return`${J4}${$}`}function Y4($,Z,J){return HH(aP($),Q4(Z,J))}function GH($,Z,J){let Q=tP($,Z,J);if(!Q)return null;let Y=iP(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function WH($,Z){e5($);let J=S0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${J4}`]).split(`
96
- `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(J4)),Q=$Z($),Y=[];for(let V of J){let X=V.slice(J4.length);if(!s1(X))continue;let H=Q4(Z,X),z=Y4($,Z,X),G=Q.get(V)??null,W=!!G&&U1(G),K=jH($,V,W),_={slug:X,chatName:H,branch:V,state:K,expectedPath:z,worktreePath:W?G:null,mounted:W,dirtyCount:null,statusLine:null,error:null};if(G&&U1(G))try{let L=S0(G,["status","--porcelain=v1","--branch"]).split(`
97
- `).filter(Boolean);_.statusLine=L[0]?.startsWith("## ")?L[0].slice(3):null,_.dirtyCount=L.filter((q)=>!q.startsWith("## ")).length}catch(j){_.error=JZ(j)}Y.push(_)}return Y.sort((V,X)=>V.slug.localeCompare(X.slug))}function KH($,Z,J){let Q=s1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);e5($);let Y=zH(Q),V=Q4(Z,Q),X=Y4($,Z,Q),H=ZD($,Y),z=$Z($).get(Y)??null,G=H&&!z&&jH($,Y,!1)==="merged"?S0($,["rev-parse","HEAD"]).trim():null;if(z){if(!ZZ(z,X))throw Error(`branch ${Y} is already mounted at ${z}`);return _H(X,Y),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(U1(X)){if(!nP(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!H)throw Error(`${X} already exists while branch ${Y} does not`)}if(H){if(S0($,["worktree","add",X,Y]),G)S0(X,["rebase",G]);return{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return S0($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function BH($,Z,J){let Q=r5($,Z,J);if(!U1(Q.worktreePath))return Q;return S0($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function r5($,Z,J){let Q=s1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);e5($);let Y=zH(Q),V=Q4(Z,Q),X=Y4($,Z,Q),H=$Z($).get(Y)??null;if(H&&!ZZ(H,X))throw Error(`branch ${Y} is already mounted at ${H}, outside managed path ${X}`);let z=H??X;if(!U1(z))return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1};if(!H)throw Error(`${z} is not a registered worktree of ${$}`);_H(z,Y);let G=S0(z,["status","--porcelain=v1"]).split(`
93
+ `:"";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(RP)}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=G9($);if(!A0(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 p2(`模型设置未确认:${Q instanceof Error?Q.message:String(Q)}`,null,{cause:Q})}this.opts.model=$,this.lastModel=J?F1($):"claude:default",this.lastEffort=null;try{await this.query.applyFlagSettings({effortLevel:Z==="default"?null:Z,ultracode:null})}catch(Q){throw new p2(`模型已切换为 ${$},但思考档位未确认:${Q instanceof Error?Q.message:String(Q)}`,$,{cause:Q})}this.opts.effort=Z,this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Q=()=>{this.off("context_compacted",Y),this.off("assistant_text",V),this.off("exit",X),this.off("error",H)},Y=()=>{if(J)return;J=!0,Q(),$()},V=(z)=>{if(J)return;if((z?.text??"").includes("Not enough messages to compact"))J=!0,Q(),Z(new l1)},X=()=>{if(J)return;J=!0,Q(),Z(Error("claude thread exited during /compact"))},H=(z)=>{if(J)return;J=!0,Q(),Z(z instanceof Error?z:Error(String(z)))};this.on("context_compacted",Y),this.on("assistant_text",V),this.once("exit",X),this.once("error",H)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Q=TP(Z);if(Q.length===0)return B("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Y={...Z,questions:Q},V=`claude_perm_${++this.requestCounter}`,X=J.toolUseID||V,H={request_id:V,tool_name:"AskUserQuestion",input:Y,tool_use_id:X},z=new Promise((G)=>{let W=(_)=>{J.signal.removeEventListener("abort",K),G(_)},K=()=>{if(!this.pendingPermissions.delete(V))return;W({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(V,{kind:"dialog",resolve:W,request:H})});return this.emitToolUseOnce(X,"AskUserQuestion",Y,null),this.emit("can_use_tool",H),z}async readLoop($){try{for await(let Z of $)this.handleMessage(Z);this.finishExit(null,null)}catch(Z){let J=Z instanceof Error?Z:Error(String(Z));if(this.expectedExit&&this.abortController.signal.aborted){B(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}B(`claude-agent-process: read loop failed: ${J.message}`),this.emit("error",J),this.finishExit(1,null)}}finishExit($,Z){if(!this.alive)return;this.alive=!1,this.turnActive=!1,this.denyPendingPermissions("claude process exited"),this.resolveExit(),B(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Q=(V)=>{if(J)return;J=!0,clearTimeout(Y),Z(V)},Y=setTimeout(()=>Q(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Q(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:B(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=F1($.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=F1(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=AP(Y.text);if(V){if(this.pendingServerToolInputs.push(V),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(NP(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,OP(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,UP(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=uX(Q.content),X=Y&&typeof Y==="object"?[typeof Y.stdout==="string"?Y.stdout:"",typeof Y.stderr==="string"?Y.stderr:""].filter(Boolean).join(`
94
+ `):"",H=V||X;this.emitToolResultOnce(Q.tool_use_id,H,Q.is_error===!0||Y?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=PP($.usage),J=$.modelUsage??$.model_usage,Q=FP(J);if(!Z&&!Q.usage)B(`claude-agent-process: result usage missing rootKeys=${p5($).join(",")||"-"} usageKeys=${p5($.usage).join(",")||"-"} modelUsageKeys=${p5(J).join(",")||"-"}`);if(this.lastUsage=Z,Q.usage)this.cumulativeUsageFromResults=q8(Q.usage),this.lastTotalUsage=q8(Q.usage);else if(Z)this.cumulativeUsageFromResults=MP(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=q8(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?q8(this.cumulativeUsageFromResults):null;if(Q.contextWindow!=null){let H=fX(this.opts.model,this.tokenSourceId);if(c5.set(H,Q.contextWindow),this.tokenSourceId)for(let[z,G]of Object.entries(J??{})){let W=G?.contextWindow;if(typeof W==="number"&&W>0)wX(this.tokenSourceId,z,W)}}this.lastContextWindow=c5.get(fX(this.opts.model,this.tokenSourceId))??Q.contextWindow??null;let Y=D8(this.opts.workDir,this.sessionId??""),V=lX(Y);if(this.lastContextTokens=vX(V)??(IX(Y)?vX(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(`
95
+ `):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 SP}from"node:os";function bP($,Z=CP){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 oX($){return typeof $==="string"&&kP.includes($)?$:null}async function M8($={}){let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (e2(),i5)),J=new Z({workDir:SP(),effort:"high",settingSources:["user"],allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(Q)=>B(`Claude model catalog MISS: ${Q.message}`));try{let Q=await bP(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 sX($="default"){let Z=v.revision($),J=new t$({accountId:$});try{await J.initialize("lodestar-models");let Q=await P1(()=>J.request("account/read",{refreshToken:!1}),"账号查询");if(z8($,Q?.account,Z),Q?.account?.type!=="chatgpt")throw Object.assign(Error("Codex 订阅未登录;发送 codex-login 或 codex-login 备注完成授权"),{code:"CODEX_AUTH_MISSING"});let Y=await P1(()=>J.request("model/list",{}),"模型查询");if(!Array.isArray(Y?.data))throw Error("Codex model/list 缺少 data 数组");let V=Y.data,X=[];for(let H of V){if(!H||H.hidden||!H.id)continue;let z=(Array.isArray(H.supportedReasoningEfforts)?H.supportedReasoningEfforts:[]).map((W)=>oX(W?.reasoningEffort)).filter((W)=>W!==null);if(!z.length)continue;let G=oX(H.defaultReasoningEffort)??z[0];X.push({model:String(H.id),display:typeof H.displayName==="string"&&H.displayName?String(H.displayName):String(H.id),efforts:z,defaultEffort:G})}if(!X.length)throw Error("Codex model/list 未返回可用模型");return X}finally{await J.close()}}async function tX($,Z){return(await y2($,Z)).map((Q)=>({model:Q,display:Q,efforts:$4,defaultEffort:"max"}))}var CP=1e4,kP,$4;var Z4=R(()=>{d4();M$();I();G8();D0();kP=["none","minimal","low","medium","high","xhigh","max","ultra"];$4=["max","xhigh","high","medium","low"]});import{existsSync as wP}from"node:fs";import{join as yP}from"node:path";function rX($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt,...$.unreportedFull===void 0?{}:{unreportedFull:$.unreportedFull}}}function _9($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[],resetCredits:null,...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(rX($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(rX($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt,resetCredits:$.resetCredits??null}}function eX($){return $===c||wP(yP(v.home($),"auth.json"))}var U8=R(()=>{f0();Q0();M$();Z4();I();D0();o$();L0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=new Map,J=(Y)=>{let V=eX(Y),X=$.model?.trim()||void 0,H=$.effort?.trim()||void 0,z={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(z.enabled=eX(Y),!z.enabled){z.models=[],z.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}z.modelCatalogState={status:"loading",updatedAt:null};try{if(z.models=await sX(Y),H)for(let G of z.models)G.defaultEffort=H;if(!X)z.defaultModel=z.models[0]?.model??"";z.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(G){if(B(`codex-sub ${Y} refreshModels MISS: ${G?.message??G}`),z.models=[],G?.code==="CODEX_AUTH_MISSING")z.enabled=!1;z.modelCatalogState={status:z.enabled?"failed":"disabled",updatedAt:Date.now(),error:G?.message??String(G)}}},spawnEnv(G){let W=l0(G);return Object.assign(W,p.codex.env),v.env(Y,W)},resolveSpawnModel(G){return G},async readUsage(){return _9(await AX(Y))}};return z},Q=J(c);return Q.forAccount=(Y)=>{if(Y===c)return Q;let V=v.revision(Y),X=Z.get(Y);if(X?.revision===V)return X.source;let H=X8(J(Y),$);return Z.set(Y,{revision:V,source:H}),H},Q}})});function $H($,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([...s(J.custom_models),...Q?.mode==="catalog"||$.kind.startsWith("packy")?s(J.models):[]])],X=[...Y];for(let W of V)if(!X.some((K)=>K.model.toLowerCase()===W.toLowerCase())){let K=Z.modelSelection?.availableModels.find((_)=>_.model===W);X.push(K?{...K,efforts:[...K.efforts]}:{model:W,display:W,origin:"custom",...i1($,J)})}let H=new Set(s(J.hidden_models)),z=J.models!==void 0?s(J.models):Q?.modelIds.length?Q.modelIds:Z.modelSelection?.modelIds??[],G=Q?.mode==="allowlist"?z.map((W)=>{let K=$.agent==="claude"?W.replace(/\[1m\]$/,""):W,_=X.find((j)=>j.model===K)??Z.models.find((j)=>j.model===W);return _?{..._,model:W}:{model:W,display:W,efforts:[],defaultEffort:null,unavailableReason:"账号目录缓存未返回该模型"}}).filter((W)=>!!W):X.filter((W)=>W.origin==="custom"||!H.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 n5($,Z,J,Q,Y,V){let X=Y&&j9.get(Y),H=$(),z=H.kind==="codex-subscription"?`${J}:${v.revision(V??c)}`:J;if(X?.active()&&X.configuration===Q&&X.identity===z)return Y;if(X?.identity===z)$H(H,Y,Z);let G={...H},W=!0,K=X?.identity===z?X.snapshot():void 0,_=new Map,j=(D)=>{H=D;let{refreshModels:F,readUsage:M,forAccount:U,...O}=D;Object.assign(G,O)},L=new i3(`token-source ${G.id}${V?`/${V}`:""} models`,vP,async()=>{let D=O8.get(z);if(!D){let A;try{A=$()}catch(y){throw G.modelCatalogState={status:G.modelCatalogState?.status==="ready"?"ready":"failed",updatedAt:G.modelCatalogState?.updatedAt??null,error:y instanceof Error?y.message:String(y)},y}let T=Promise.resolve().then(()=>A.refreshModels()).then(()=>({source:A}),(y)=>({source:A,error:y})).finally(()=>{if(O8.get(z)?.promise===T)O8.delete(z)});D={configuration:Q,promise:T},O8.set(z,D)}let F=await D.promise,M=F.source,U=F.error;if(D.configuration!==Q){if(M=$(),F.source.modelCatalogState?.status==="ready")$H(M,F.source,Z);else if(M.modelCatalogState=F.source.modelCatalogState&&{...F.source.modelCatalogState},!F.source.enabled)M.enabled=!1}if(!W)return;if(U!==void 0&&!M.modelCatalogState?.error)M.modelCatalogState={status:"failed",updatedAt:Date.now(),error:U instanceof Error?U.message:String(U)};let O=M.modelCatalogState?.error;if(O&&e0(O)){if(K={state:"no_credentials",windows:[],reason:O},G.kind==="codex-subscription")L1(V??c)}if(M.modelCatalogState?.status==="failed"||U){let A=M.modelCatalogState?.error??(U instanceof Error?U.message:String(U));if(G.modelCatalogState?.status==="ready"&&!e0(A))G.modelCatalogState={...G.modelCatalogState,error:A};else j(M);throw U??Error(A)}j(M)},X?.identity===z?X.model.nextRefreshAt:0),q=new i3(`token-source ${G.id}${V?`/${V}`:""} usage`,fP,async()=>{let D;try{D=await H.readUsage()}catch(F){let M=F instanceof Error?F.message:String(F);if(W&&(K?.state!=="ok"||e0(M)))K={state:e0(M)?"no_credentials":"network",windows:[],reason:M};throw F}if(!W)return;if(K?.state!=="ok"||!["network","rate_limited"].includes(D.state)||e0(D.reason))K=D;if(D.state!=="ok"&&D.state!=="not_applicable"&&D.state!=="no_credentials")throw Object.assign(Error(D.reason??D.state),{retryAfterMs:D.retryAfterMs})},X?.identity===z?X.usage.nextRefreshAt:0);if(G.refreshModels=()=>L.refresh(),G.readUsage=async()=>!G.enabled?{state:"no_credentials",windows:[],reason:G.modelCatalogState?.error}:G.kind==="codex-subscription"?_9(n1(V)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"}):K??{state:G.enabled?"network":"no_credentials",windows:[],reason:"额度缓存尚未就绪,后台刷新中"},H.forAccount)G.forAccount=(D)=>{if(D===c)return G;let F=v.revision(D),M=_.get(D);if(M?.revision===F)return M.source;if(M)q9(M.source);let U=X?.baseIdentity===J?X.children.get(D):void 0,O=n5(()=>$().forAccount(D),Z,J,Q,U?.revision===F?U.source:void 0,D);return _.set(D,{revision:F,source:O}),O};return j9.set(G,{baseIdentity:J,identity:z,configuration:Q,model:L,usage:q,children:_,snapshot:()=>K,active:()=>W,dispose(){W=!1,L.dispose(),q.dispose();for(let D of _.values())q9(D.source)}}),G}function q9($){j9.get($)?.dispose()}function ZH($,Z){let J=$&&j9.get($),Q=J?.children.get(Z);if(Q)q9(Q.source),J.children.delete(Z)}function JH($){return j9.get($)?.usage.refresh()??Promise.resolve()}var vP=300000,fP=60000,j9,O8;var A8=R(()=>{H5();D0();o$();M$();U8();s$();j9=new WeakMap,O8=new Map});function IP($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!hP.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 P9{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 QH($){let Z=$.now??Date.now;return{accept(J){let Q=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Q))}}}class o5{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 a5($){if(Array.isArray($))return`[${$.map(a5).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)}:${a5(J)}`).join(",")}}`}function gP($){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${a5(V)}`}function mP($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${gP($)}`,...["agent_identity_page","model_page","model_list_open","model_add","model_remove","model_custom_remove","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function pP(){return new Promise(($)=>setTimeout($,0))}function L9($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function YH($){let Z=$.afterAck??pP,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=IP(Y);if(V)return $.responses.invalid(Y,V);let X=mP(Y),H=X.deliveryKey?[X.deliveryKey,X.businessKey]:[X.businessKey],z=$.deduper.claimAll(H);if(z==="inflight")return $.responses.inflight(Y);if(z==="completed")return $.responses.completed(Y);let G=$.actor.tryEnqueue($.scope(Y),async()=>{try{await Z()}catch(_){$.deduper.failAll(H),J(_);return}let W;try{W=await $.execute(Y)}catch(_){L9($.deduper,X,!0),await Q(()=>$.presentExecutionFailure(Y,_));return}await Q(async()=>{try{await $.present(Y,W)}catch(_){await $.presentPresentationFailure(Y,_)}});let K;try{K=$.completion(Y,W)}catch(_){L9($.deduper,X,!1),J(_);return}if(K){let _=K.then((j)=>{L9($.deduper,X,j==="complete")},(j)=>{L9($.deduper,X,!1),J(j)});$.track(_);return}L9($.deduper,X,$.businessSucceeded(Y,W))});if(!G.accepted)return $.deduper.failAll(H),$.responses.closed(Y);return $.track(G.completion),G.completion.catch(J),$.responses.accepted(Y)}}}var hP;var s5=R(()=>{hP=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 cP}from"node:async_hooks";class VH{actor=new P9;context=new cP;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 U$($,Z){return lP.run($,Z)}var lP;var t5=R(()=>{s5();lP=new VH});import{execFileSync as uP}from"node:child_process";import{existsSync as M1,readdirSync as dP,readFileSync as iP,realpathSync as R8,statSync as nP}from"node:fs";import{dirname as aP,join as HH,resolve as oP}from"node:path";async function T8($,Z){let J=R8($),Q=process.platform==="win32"?J.toLowerCase():J,Y=N8.get(Q)??Promise.resolve(),V,X=new Promise((z)=>{V=z}),H=Y.catch(()=>{}).then(()=>X);N8.set(Q,H),await Y.catch(()=>{});try{return await Z()}finally{if(V(),N8.get(Q)===H)N8.delete(Q)}}function s1($){let Z=$.trim();if(!sP.test(Z))return null;return Z}function x8($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function Q4($,Z){return`${$}[${Z}]`}function zH($){return`${J4}${$}`}function Y4($,Z,J){return HH(aP($),Q4(Z,J))}function GH($,Z,J){let Q=tP($,Z,J);if(!Q)return null;let Y=iP(Q.path,"utf8").trim();if(!Y)return null;return{path:Q.path,content:Y,slug:Q.slug}}function WH($,Z){e5($);let J=S0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${J4}`]).split(`
96
+ `).map((V)=>V.trim()).filter(Boolean).filter((V)=>V.startsWith(J4)),Q=$Z($),Y=[];for(let V of J){let X=V.slice(J4.length);if(!s1(X))continue;let H=Q4(Z,X),z=Y4($,Z,X),G=Q.get(V)??null,W=!!G&&M1(G),K=jH($,V,W),_={slug:X,chatName:H,branch:V,state:K,expectedPath:z,worktreePath:W?G:null,mounted:W,dirtyCount:null,statusLine:null,error:null};if(G&&M1(G))try{let L=S0(G,["status","--porcelain=v1","--branch"]).split(`
97
+ `).filter(Boolean);_.statusLine=L[0]?.startsWith("## ")?L[0].slice(3):null,_.dirtyCount=L.filter((q)=>!q.startsWith("## ")).length}catch(j){_.error=JZ(j)}Y.push(_)}return Y.sort((V,X)=>V.slug.localeCompare(X.slug))}function KH($,Z,J){let Q=s1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);e5($);let Y=zH(Q),V=Q4(Z,Q),X=Y4($,Z,Q),H=ZD($,Y),z=$Z($).get(Y)??null,G=H&&!z&&jH($,Y,!1)==="merged"?S0($,["rev-parse","HEAD"]).trim():null;if(z){if(!ZZ(z,X))throw Error(`branch ${Y} is already mounted at ${z}`);return _H(X,Y),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!1}}if(M1(X)){if(!nP(X).isDirectory())throw Error(`${X} exists but is not a directory`);if(!H)throw Error(`${X} already exists while branch ${Y} does not`)}if(H){if(S0($,["worktree","add",X,Y]),G)S0(X,["rebase",G]);return{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!1,createdWorktree:!0}}return S0($,["worktree","add","-b",Y,X,"HEAD"]),{slug:Q,chatName:V,branch:Y,worktreePath:X,createdBranch:!0,createdWorktree:!0}}function BH($,Z,J){let Q=r5($,Z,J);if(!M1(Q.worktreePath))return Q;return S0($,["worktree","remove",Q.worktreePath]),{...Q,removedWorktree:!0}}function r5($,Z,J){let Q=s1(J);if(!Q)throw Error(`invalid worktree name "${J}"`);e5($);let Y=zH(Q),V=Q4(Z,Q),X=Y4($,Z,Q),H=$Z($).get(Y)??null;if(H&&!ZZ(H,X))throw Error(`branch ${Y} is already mounted at ${H}, outside managed path ${X}`);let z=H??X;if(!M1(z))return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1};if(!H)throw Error(`${z} is not a registered worktree of ${$}`);_H(z,Y);let G=S0(z,["status","--porcelain=v1"]).split(`
98
98
  `).filter(Boolean);if(G.length>0){let W=G.slice(0,8).join(`
99
99
  `);throw Error(`worktree has uncommitted changes:
100
- ${W}`)}return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1}}function e5($){if(!U1($))throw Error(`project directory does not exist: ${$}`);let Z=S0($,["rev-parse","--show-toplevel"]).trim();if(R8(Z)!==R8($))throw Error(`${$} is not the git repository root (${Z})`)}function _H($,Z){let J=S0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function tP($,Z,J){let Q=rP($);if(!Q?.startsWith(J4))return null;let Y=Q.slice(J4.length);if(!s1(Y))throw Error(`invalid worktree branch "${Q}"`);let V=Y4(Z,J,Y);if(!ZZ($,V))return null;let X=$D($,eP(Y));return X?{path:X,slug:Y}:null}function rP($){if(!U1($))return null;try{return S0($,["branch","--show-current"]).trim()||null}catch(Z){if(JD(Z))return null;throw Z}}function eP($){return $.split("-",1)[0]??$}function $D($,Z){let J=`agents.${Z}.md`.toLowerCase(),Q=dP($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?HH($,Q[0]):null}function ZD($,Z){try{return S0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function jH($,Z,J){let Q=S0($,["rev-parse",Z]).trim(),Y=S0($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(XH($,Z,"HEAD"))return"merged";if(XH($,"HEAD",Z))return"active";return"stale"}function XH($,Z,J){try{return S0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function $Z($){let Z=new Map,J=S0($,["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 ZZ($,Z){let J=(Q)=>{let Y=U1(Q)?R8(Q):oP(Q);return process.platform==="win32"?Y.toLowerCase():Y};return J($)===J(Z)}function S0($,Z){try{return uP("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(JZ(J))}}function JZ($){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 JD($){return/not a git repository/i.test(JZ($))}var J4="work/",sP,N8;var QZ=R(()=>{sP=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,N8=new Map});import{lstatSync as YD,realpathSync as VD,statSync as XD}from"node:fs";import{basename as HD,dirname as qH,isAbsolute as zD,join as LH,resolve as GD}from"node:path";function WD($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function YZ($,Z,J){let Q=WD($),Y=x8(Q),V=J[Y]?.cwd?.trim()||LH(Z,Y);if(Q===Y)return V;return Y4(V,Y,Q.slice(Y.length+1,-1))}function w$($){if(!zD($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=PH(GD($));return process.platform==="win32"?Z.toLowerCase():Z}function PH($){try{let Z=VD($);if(!XD(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||qH($)===$)throw Z;try{if(YD($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return LH(PH(qH($)),HD($))}}function DH($,Z,J){let Q=w$($),Y,V=new Map;for(let[X,H]of Object.entries(J)){if(w$(YZ(X,Z,J))!==Q)continue;Y??={cwd:$};for(let z of["settingSources","strictMcp","tools","loadProjectMcp"]){let G=H[z];if(G===void 0)continue;if(Y[z]!==void 0&&Y[z]!==G)throw Error(`同一工作目录的项目配置冲突: ${V.get(z)} / ${X}, ${z} (${$})`);Object.assign(Y,{[z]:G}),V.set(z,X)}}return Y}var E8=R(()=>{QZ()});function KD($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function VZ($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let H=J.exec($);if(!H)break;let z=H[1],G=new RegExp(`^(?: {0,3})${KD(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=H.index+H[0].length;let W=G.exec($),K=W?W.index+W[0].length:$.length;Z.push({start:H.index,end:K}),Q=K}let Y=[...Z],V=[],X=0;for(let H of Z){if(X<H.start)V.push({start:X,end:H.start});X=H.end}if(X<$.length)V.push({start:X,end:$.length});for(let H of V){let z=$.slice(H.start,H.end),G=/(`+)[^\n]*?\1/g,W;while((W=G.exec(z))!==null)Y.push({start:H.start+W.index,end:H.start+W.index+W[0].length})}return Y.sort((H,z)=>H.start-z.start)}function XZ($,Z){if(!$)return $;let J=VZ($);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 BD($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function FH($){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 M1($){if(Array.isArray($))return $.map((Q)=>M1(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=M1(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=HZ(Z.content);return J}function $0($){return XZ($,(Z)=>_D(FH(BD(Z))))}function _D($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
100
+ ${W}`)}return{slug:Q,chatName:V,branch:Y,worktreePath:z,removedWorktree:!1}}function e5($){if(!M1($))throw Error(`project directory does not exist: ${$}`);let Z=S0($,["rev-parse","--show-toplevel"]).trim();if(R8(Z)!==R8($))throw Error(`${$} is not the git repository root (${Z})`)}function _H($,Z){let J=S0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function tP($,Z,J){let Q=rP($);if(!Q?.startsWith(J4))return null;let Y=Q.slice(J4.length);if(!s1(Y))throw Error(`invalid worktree branch "${Q}"`);let V=Y4(Z,J,Y);if(!ZZ($,V))return null;let X=$D($,eP(Y));return X?{path:X,slug:Y}:null}function rP($){if(!M1($))return null;try{return S0($,["branch","--show-current"]).trim()||null}catch(Z){if(JD(Z))return null;throw Z}}function eP($){return $.split("-",1)[0]??$}function $D($,Z){let J=`agents.${Z}.md`.toLowerCase(),Q=dP($).filter((Y)=>Y.toLowerCase()===J).sort();if(Q.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Q.join(", ")}`);return Q[0]?HH($,Q[0]):null}function ZD($,Z){try{return S0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function jH($,Z,J){let Q=S0($,["rev-parse",Z]).trim(),Y=S0($,["rev-parse","HEAD"]).trim();if(Q===Y)return J?"active":"merged";if(XH($,Z,"HEAD"))return"merged";if(XH($,"HEAD",Z))return"active";return"stale"}function XH($,Z,J){try{return S0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function $Z($){let Z=new Map,J=S0($,["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 ZZ($,Z){let J=(Q)=>{let Y=M1(Q)?R8(Q):oP(Q);return process.platform==="win32"?Y.toLowerCase():Y};return J($)===J(Z)}function S0($,Z){try{return uP("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(JZ(J))}}function JZ($){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 JD($){return/not a git repository/i.test(JZ($))}var J4="work/",sP,N8;var QZ=R(()=>{sP=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,N8=new Map});import{lstatSync as YD,realpathSync as VD,statSync as XD}from"node:fs";import{basename as HD,dirname as qH,isAbsolute as zD,join as LH,resolve as GD}from"node:path";function WD($){return $.replace(/\*[0-9]{4}-[0-9]{4}(?:-[0-9]+)?$/,"")}function YZ($,Z,J){let Q=WD($),Y=x8(Q),V=J[Y]?.cwd?.trim()||LH(Z,Y);if(Q===Y)return V;return Y4(V,Y,Q.slice(Y.length+1,-1))}function w$($){if(!zD($))throw Error(`工作目录必须是绝对路径: ${$}`);let Z=PH(GD($));return process.platform==="win32"?Z.toLowerCase():Z}function PH($){try{let Z=VD($);if(!XD(Z).isDirectory())throw Error(`工作目录不是文件夹: ${$}`);return Z}catch(Z){if(Z?.code!=="ENOENT"||qH($)===$)throw Z;try{if(YD($).isSymbolicLink())throw Z}catch(J){if(J===Z||J?.code!=="ENOENT")throw J}return LH(PH(qH($)),HD($))}}function DH($,Z,J){let Q=w$($),Y,V=new Map;for(let[X,H]of Object.entries(J)){if(w$(YZ(X,Z,J))!==Q)continue;Y??={cwd:$};for(let z of["settingSources","strictMcp","tools","loadProjectMcp"]){let G=H[z];if(G===void 0)continue;if(Y[z]!==void 0&&Y[z]!==G)throw Error(`同一工作目录的项目配置冲突: ${V.get(z)} / ${X}, ${z} (${$})`);Object.assign(Y,{[z]:G}),V.set(z,X)}}return Y}var E8=R(()=>{QZ()});function KD($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function VZ($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Q=0;while(Q<$.length){J.lastIndex=Q;let H=J.exec($);if(!H)break;let z=H[1],G=new RegExp(`^(?: {0,3})${KD(z[0])}{${z.length},}[ \\t]*(?:\\n|$)`,"gm");G.lastIndex=H.index+H[0].length;let W=G.exec($),K=W?W.index+W[0].length:$.length;Z.push({start:H.index,end:K}),Q=K}let Y=[...Z],V=[],X=0;for(let H of Z){if(X<H.start)V.push({start:X,end:H.start});X=H.end}if(X<$.length)V.push({start:X,end:$.length});for(let H of V){let z=$.slice(H.start,H.end),G=/(`+)[^\n]*?\1/g,W;while((W=G.exec(z))!==null)Y.push({start:H.start+W.index,end:H.start+W.index+W[0].length})}return Y.sort((H,z)=>H.start-z.start)}function XZ($,Z){if(!$)return $;let J=VZ($);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 BD($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function FH($){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 U1($){if(Array.isArray($))return $.map((Q)=>U1(Q));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Q,Y]of Object.entries(Z))J[Q]=U1(Y);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=HZ(Z.content);return J}function $0($){return XZ($,(Z)=>_D(FH(BD(Z))))}function _D($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
101
101
  \`\`\`
102
102
  ${J.trim()}
103
103
  \`\`\`
@@ -105,21 +105,21 @@ ${J.trim()}
105
105
  \`\`\`
106
106
  ${J.trim()}
107
107
  \`\`\`
108
- `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function HZ($){return XZ($,FH)}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 zZ($){let Z=await KZ("feishu chat.get",()=>W0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)S8("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 GZ($,Z){let J=await KZ("feishu tasklist.create",()=>W0.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)S8("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 KZ("feishu tasklist.delete",()=>W0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)S8("feishu tasklist.delete",Z)}function UH($,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 ${k(Z)}${V?` missing_scopes=${V}`:""}`}async function KZ($,Z){try{return await Z()}catch(J){S8($,J)}}function S8($,Z){throw Error(UH($,Z))}var MH=R(()=>{e()});var J0={};d$(J0,{writeAliveMarker:()=>CZ,urgentApp:()=>e1,uploadImageKey:()=>IZ,uploadAndSend:()=>R9,updateCard:()=>K4,unbindSessionChat:()=>b8,tempProjectName:()=>r$,tempChatName:()=>TZ,setPendingConversationLaunchChecked:()=>N1,sendTextRaw:()=>g,sendText:()=>b,sendImage:()=>p8,sendFile:()=>cH,sendCard:()=>i,sanitizeSessionName:()=>mZ,resolveProjectDir:()=>X4,replaceTurnAnchors:()=>J$,registerTempSessionLease:()=>FZ,refreshChatList:()=>A9,readAliveMarker:()=>bZ,provisionProject:()=>gZ,projectProfileForDirectory:()=>U9,projectProfile:()=>DD,preferredChatForSession:()=>_0,loadTempSessionLeases:()=>DZ,loadSessionTurnsMap:()=>NZ,loadSessionResumeMap:()=>OZ,loadSessionModelMap:()=>xZ,loadSessionChatMap:()=>MZ,listNormalChatIdsByName:()=>h8,isOpenAIChatGPTAuthenticated:()=>T9,hasTempSessionLease:()=>UZ,getTurnAnchors:()=>z4,getTenantToken:()=>y$,getSessionResumeRef:()=>A1,getSessionModelSelection:()=>EZ,getSessionBranchBase:()=>G4,getPendingConversationLaunch:()=>W4,getChatTailMessageId:()=>hZ,formatFeishuApiError:()=>UH,findNormalChatIdByName:()=>I8,fetchChatOwnerOpenId:()=>zZ,fetchChatName:()=>fZ,ensureChatForSession:()=>kZ,downloadAttachment:()=>N9,disbandChatForSessionExact:()=>vZ,disbandChatForSession:()=>yZ,deleteTasklistByGuid:()=>WZ,deleteReaction:()=>g0,createTempChatForSession:()=>wZ,createTasklistWithOwner:()=>GZ,client:()=>W0,clearSessionResumeChecked:()=>H4,clearSessionConversationState:()=>SZ,chatNameCache:()=>j0,chatIdForSession:()=>f8,bindSessionToChat:()=>V4,bindSessionResumeChecked:()=>O9,bindSessionModelChecked:()=>R1,bindSessionModel:()=>RD,appendTurnAnchorChecked:()=>RZ,addReaction:()=>Q$,PROJECTS_ROOT:()=>PZ,MAX_UPLOAD_BYTES:()=>m8});import*as y8 from"@larksuiteoapi/node-sdk";import{execSync as jD}from"node:child_process";import{randomUUID as v8}from"node:crypto";import{mkdirSync as _Z,readFileSync as r1,statSync as EH,writeFileSync as SH}from"node:fs";import{readFile as qD}from"node:fs/promises";import{homedir as OH}from"node:os";import{basename as t1,extname as LD,isAbsolute as CH,join as jZ}from"node:path";import{sync as PD}from"cross-spawn";function qZ(){let $={};for(let[Z,J]of Z$)$[Z]=J;o(h7,$)}function DZ(){Z$.clear();try{let $=JSON.parse(r1(h7,"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"||!r$(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}Z$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}B(`feishu: loaded ${Z$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function FZ($,Z){if(!r$($))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 Z$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=Z$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};Z$.set(Z,Q);try{qZ()}catch(Y){if(J)Z$.set(Z,J);else Z$.delete(Z);throw Y}}function UZ($,Z){let J=Z$.get(Z);return J?.sessionName===$&&J.chatId===Z}function DD($){return p.projects[$]}function X4($){return YZ($,PZ,p.projects)}function U9($){return DH($,PZ,p.projects)}function d0($,Z){let J=F$(Z);return new y0(`${$} failed ${k(Z)}`,J.status,J.code,J.retryAfter,J.logId,J.message)}function M9($,Z={}){return X0($,{...Z,signal:Z.signal??AbortSignal.timeout(wH)})}async function yH($,Z,J){let Q=Z.signal??AbortSignal.timeout(wH);try{return await z$(await M9($,{...Z,signal:Q}),J)}catch(Y){if(Q.aborted&&Q.reason?.name==="TimeoutError")throw Q.reason;throw Y}}async function y$(){if(C8&&Date.now()<AH)return C8;return BZ??=(async()=>{let $=await yH("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:bH,app_secret:kH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return C8=$.tenant_access_token,AH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,C8})().finally(()=>{BZ=null}),BZ}function MZ(){try{let $=JSON.parse(r1(w7,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")_0.set(Z,J);B(`feishu: loaded ${_0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function vH(){try{LZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function LZ(){let $={};for(let[Z,J]of _0)$[Z]=J;o(w7,$)}function V4($,Z){if(_0.get($)===Z)return;let J=_0.get($);_0.set($,Z),vH(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function b8($){let Z=_0.get($);if(!Z)return;_0.delete($),vH(),B(`feishu: unbound session "${$}" from ${Z}`)}function D9($,Z){let J=M0.get($)??{};J[Z.provider]=Z,M0.set($,J)}function NH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=C$(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"||!CH(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function RH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!C$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!CH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function UD($,Z,J){if(typeof $!=="string")return RH($);if(!Z)throw Error("cannot bind a conversation without a provider");return RH({provider:Z,sessionId:$,cwd:J??null})}function OZ(){try{let $=JSON.parse(r1(y7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");M0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){D9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=NH(Q);if(Y){D9(Z,Y);continue}for(let V of W5){let X=Q[V];if(typeof X==="string"&&X.trim()){D9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let H=NH(X,V);if(H)D9(Z,H)}}B(`feishu: loaded ${M0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function k8(){let $={};for(let[Z,J]of M0){let Q={};if(J.codex)Q.codex={...J.codex};if(J.claude)Q.claude={...J.claude};if(J.dsh)Q.dsh={...J.dsh};$[Z]=Q}o(y7,$)}function O9($,Z,J,Q){let Y=UD(Z,J,Q),V=M0.get($),X=V?{...V}:void 0,H=V?.[Y.provider];if(H?.sessionId===Y.sessionId&&H.cwd===Y.cwd)return;D9($,Y);try{k8()}catch(z){if(X)M0.set($,X);else M0.delete($);throw z}}function A1($,Z="codex"){let J=M0.get($)?.[Z];return J?{...J}:null}function H4($,Z){let J=M0.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)M0.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)M0.delete($);else M0.set($,Y)}try{k8()}catch(Y){throw M0.set($,Q),Y}}function fH($){if(!$||typeof $!=="object")return null;let Z=$;if(!C$(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 hH($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=fH(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 IH($){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=fH(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=hH(Z.through);return Y?{kind:"fork",source:J,through:Y}:null})();if(!Q)return null;try{U0(Q,J.provider)}catch{return null}return Q}function MD($){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 OD($,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=hH(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:MD(J.writes)}}function AD($){if(!$||typeof $!=="object")return null;let Z=$,J=IH(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 AZ($){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(r1(v7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");Z0.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let V,X,H=null;if(Array.isArray(Y))V=Y,X=null;else if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let K=Y;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(V=K.anchors,K.base===null)X=null;else{let _=IH(K.base);if(!_){J++;continue}X=_}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let _=AD(K.pendingLaunch);if(!_){J++;continue}H=_}}else{J++;continue}let z=M0.get(Q),G=z?.claude!==void 0&&z.codex===void 0?"claude":null,W=[];for(let K of V){let _=OD(K,G);if(_)W.push(_);else J++}if(W.length||X!==null||H)Z0.set(Q,{base:X,anchors:W,...H?{pendingLaunch:H}:{}}),Z+=W.length}if(B(`feishu: loaded ${Z} turn anchors across ${Z0.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 F9(){let $={};for(let[Z,J]of Z0)$[Z]=J;o(v7,$)}function RZ($,Z){let J=Z0.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>TH){let V=Q.splice(0,Q.length-TH),X=V[V.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}Z0.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{F9()}catch(V){if(J)Z0.set($,J);else Z0.delete($);throw V}}function z4($){return Z0.get($)?.anchors??[]}function G4($){return Z0.get($)?.base??null}function W4($){let Z=Z0.get($)?.pendingLaunch;return Z?AZ(Z):null}function N1($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");U0(Z.launch,"claude",Z.launch.source.cwd)}let J=Z0.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)Z0.delete($);else Z0.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:AZ(Z)}:{}});try{F9()}catch(V){if(J)Z0.set($,J);else Z0.delete($);throw V}}function J$($,Z,J,Q){let Y=Z0.get($),V=Q===void 0?Y?.pendingLaunch:Q??void 0,X=V?AZ(V):void 0;if(Z.length===0&&J===null&&!X)Z0.delete($);else Z0.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{F9()}catch(H){if(Y)Z0.set($,Y);else Z0.delete($);throw H}}function r$($){return xH.test($)?$.replace(xH,""):null}function TZ($,Z=[]){let J=new Date,Q=(H)=>String(H).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,V=new Set([...j0.values(),...Z0.keys(),...Z]),X=`${$}*${Y}`;for(let H=2;V.has(X);H++)X=`${$}*${Y}-${H}`;return X}function xZ(){try{let $=JSON.parse(r1(f7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){I0.set(Z,{provider:m2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,V=C$(Y)?Y:typeof Q==="string"&&Q.trim()?m2(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(V==="claude"&&!X)continue;let{effort:H,tokenSourceId:z}=J,G=typeof z==="string"&&z.trim()?z.trim():null,W=V==="dsh"?F0(H)?H:null:V==="claude"?A0(H)?H:null:W$(H)?H: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 ND(){try{w8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function w8(){let $={};for(let[Z,J]of I0)$[Z]=J;o(f7,$)}function RD($,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}:{}}),ND()}function R1($,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{w8()}catch(H){if(V)I0.set($,V);else I0.delete($);throw H}}function EZ($){let Z=I0.get($);if(Z)return Z;let J=r$($);return J?I0.get(J)??null:null}function SZ($){let Z=_0.get($),J=M0.get($),Q=I0.get($),Y=Z0.get($),V=[...Z$.entries()].filter(([,X])=>X.sessionName===$);_0.delete($),M0.delete($),I0.delete($),Z0.delete($);for(let[X]of V)Z$.delete(X);try{LZ(),k8(),w8(),F9(),qZ()}catch(X){if(Z)_0.set($,Z);if(J)M0.set($,J);if(Q)I0.set($,Q);if(Y)Z0.set($,Y);for(let[z,G]of V)Z$.set(z,G);let H=[X];for(let z of[LZ,k8,w8,F9,qZ])try{z()}catch(G){H.push(G)}throw H.length===1?H[0]:AggregateError(H,`failed to clear and restore conversation state for ${$}`)}}function CZ($){o(g7,$)}function bZ(){let $;try{$=r1(g7,"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 f8($){let Z=_0.get($);if(Z){let Q=j0.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 j0)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 A9(){try{let $;do{let Z=await W0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});if(Z.code&&Z.code!==0)throw d0("feishu chat.list",Z);for(let J of Z.data?.items??[])if(J.chat_id&&J.name)j0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${j0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function h8(){let $=new Map,Z;do{let J=await W0.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw d0("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;j0.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 I8($){let Z=_0.get($);if(Z&&j0.get(Z)===$){let V=await gH(Z);if(V.name===$&&mH(V.status))return Z;j0.delete(Z),b8($)}let Q=(await h8()).get($)??[];if(Q.length===0)return null;let Y=_0.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 kZ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await I8($);if(J){let V=await TD(J,Z);return V4($,J),{chatId:J,created:!1,joined:V}}let Q=await W0.im.chat.create({params:{user_id_type:"open_id",uuid:v8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw d0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return j0.set(Y,$),V4($,Y),{chatId:Y,created:!0,joined:!0}}async function wZ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await I8($))throw Error(`temporary group name already exists: ${$}`);let Q=await W0.im.chat.create({params:{user_id_type:"open_id",uuid:v8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw d0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return j0.set(Y,$),V4($,Y),{chatId:Y,created:!0,joined:!0}}async function yZ($){let Z=await I8($);if(!Z)return b8($),{chatId:null,disbanded:!1};let J=await W0.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw d0("feishu chat.delete",J);if(j0.delete(Z),_0.get($)===Z)b8($);return{chatId:Z,disbanded:!0}}async function vZ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await gH(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!mH(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await W0.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw d0("feishu chat.delete",Q);return j0.delete(Z),{chatId:Z,disbanded:!0}}async function TD($,Z){let J;do{let Y=await W0.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 d0("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 W0.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw d0("feishu chatMembers.create",Q);return!0}async function fZ($){try{let Z=await y$(),J=await M9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}}),Y=(await z$(J,`fetchChatName ${$}`)).data?.name;if(typeof Y==="string"&&Y)return j0.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 g8($,Z,J,Q,Y){let V=v8();try{return await p1(`send${$} chat=${Z}`,async()=>{let X=await W0.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 d0(`send${$}`,X);let H=X?.data?.message_id;if(typeof H!=="string"||!H.trim())throw Error(`send${$} message_id MISS`);return H})}catch(X){return Y?.(X),null}}async function gH($){let Z=await W0.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw d0("feishu chat.get",Z);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function mH($){return $===null||$==="normal"}async function b($,Z,J){return M$($,()=>g8("Text",$,"text",JSON.stringify({text:Z}),J))}async function i($,Z,J){return M$($,()=>g8("Card",$,"interactive",JSON.stringify(M1(Z)),J))}async function hZ($){let Z=await W0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw d0("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 K4($,Z){let J=await W0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(M1(Z))}});if(J?.code!==0)throw d0("feishu message.patch",J)}async function g($,Z){return M$($,()=>xD($,Z))}async function xD($,Z){try{let J=await y$(),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 z$(Q,`sendTextRaw chat=${$}`)).data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function Q$($,Z){if(!$)return null;try{let J=await W0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}});if(J?.code&&J.code!==0)throw d0("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 W0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}});if(J?.code&&J.code!==0)throw d0("feishu messageReaction.delete",J)}catch(J){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function e1($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await y$(),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 z$(Y,`urgentApp ${$}`)).data?.invalid_user_id_list??[],H=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${H}${X.length?` invalid=${X.length}`:""}`)}catch(Y){B(`feishu: urgentApp ${$} failed: ${Y}`)}}async function N9($,Z,J,Q){try{let Y=await y$(),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 z$(X,`download ${J}`);let H=Buffer.from(await X.arrayBuffer());_Z(m7,{recursive:!0});let z=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=jZ(m7,`${Date.now()}-${v8()}-${z}`);return SH(G,H,{flag:"wx"}),B(`feishu: downloaded ${J} ${G} (${H.length}B)`),G}catch(Y){B(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function SD($){return ED.has(LD($).toLowerCase())}async function pH($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Q;return p1(`${J} ${$}`,async()=>{if(Q??=new Blob([Uint8Array.from(await qD($))]),Q.size>m8)throw Error(`${t1($)} 超过 30 MB`);let Y=await y$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",t1($));V.append(Z,Q,t1($));let H=(await yH(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:V},J)).data?.[`${Z}_key`];if(typeof H!=="string"||!H.trim())throw Error(`${J} ${Z}_key MISS`);return H})}async function IZ($,Z){try{let J=EH($);if(!J.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),Z?.(Error("路径不是普通文件")),null;if(J.size>m8)return B(`feishu: uploadImageKey oversize — ${$} (${(J.size/1024/1024).toFixed(1)} MB)`),Z?.(Error(`${t1($)} 超过 30 MB`)),null}catch(J){return B(`feishu: uploadImageKey stat failed — ${$}: ${J}`),Z?.(J),null}try{return await pH($,"image")}catch(J){return Z?.(J),null}}async function p8($,Z,J){return M$($,()=>g8("Image",$,"image",JSON.stringify({image_key:Z}),J))}async function cH($,Z,J){return M$($,()=>g8("File",$,"file",JSON.stringify({file_key:Z}),J))}async function R9($,Z){try{let Y=EH(Z);if(!Y.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await b($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>m8)return B(`feishu: uploadAndSend oversize — ${Z} (${Y.size}B)`),await b($,`❌ 出站文件: ${t1(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=SD(Z)?"image":"file",Q=J==="image"?"出站图片":"出站文件";try{let Y=await pH(Z,J),V,X=(z)=>{V=z},H=await(J==="image"?p8($,Y,X):cH($,Y,X));if(!H)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await b($,`❌ ${Q}发送失败: ${t1(Z)}(上传已完成)
108
+ `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function HZ($){return XZ($,FH)}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 zZ($){let Z=await KZ("feishu chat.get",()=>W0.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)S8("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 GZ($,Z){let J=await KZ("feishu tasklist.create",()=>W0.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)S8("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 KZ("feishu tasklist.delete",()=>W0.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)S8("feishu tasklist.delete",Z)}function MH($,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 ${k(Z)}${V?` missing_scopes=${V}`:""}`}async function KZ($,Z){try{return await Z()}catch(J){S8($,J)}}function S8($,Z){throw Error(MH($,Z))}var UH=R(()=>{e()});var J0={};d$(J0,{writeAliveMarker:()=>CZ,urgentApp:()=>e1,uploadImageKey:()=>IZ,uploadAndSend:()=>R9,updateCard:()=>K4,unbindSessionChat:()=>b8,tempProjectName:()=>r$,tempChatName:()=>TZ,setPendingConversationLaunchChecked:()=>N1,sendTextRaw:()=>g,sendText:()=>b,sendImage:()=>p8,sendFile:()=>cH,sendCard:()=>i,sanitizeSessionName:()=>mZ,resolveProjectDir:()=>X4,replaceTurnAnchors:()=>J$,registerTempSessionLease:()=>FZ,refreshChatList:()=>A9,readAliveMarker:()=>bZ,provisionProject:()=>gZ,projectProfileForDirectory:()=>M9,projectProfile:()=>DD,preferredChatForSession:()=>_0,loadTempSessionLeases:()=>DZ,loadSessionTurnsMap:()=>NZ,loadSessionResumeMap:()=>OZ,loadSessionModelMap:()=>xZ,loadSessionChatMap:()=>UZ,listNormalChatIdsByName:()=>h8,isOpenAIChatGPTAuthenticated:()=>T9,hasTempSessionLease:()=>MZ,getTurnAnchors:()=>z4,getTenantToken:()=>y$,getSessionResumeRef:()=>A1,getSessionModelSelection:()=>EZ,getSessionBranchBase:()=>G4,getPendingConversationLaunch:()=>W4,getChatTailMessageId:()=>hZ,formatFeishuApiError:()=>MH,findNormalChatIdByName:()=>I8,fetchChatOwnerOpenId:()=>zZ,fetchChatName:()=>fZ,ensureChatForSession:()=>kZ,downloadAttachment:()=>N9,disbandChatForSessionExact:()=>vZ,disbandChatForSession:()=>yZ,deleteTasklistByGuid:()=>WZ,deleteReaction:()=>g0,createTempChatForSession:()=>wZ,createTasklistWithOwner:()=>GZ,client:()=>W0,clearSessionResumeChecked:()=>H4,clearSessionConversationState:()=>SZ,chatNameCache:()=>j0,chatIdForSession:()=>f8,bindSessionToChat:()=>V4,bindSessionResumeChecked:()=>O9,bindSessionModelChecked:()=>R1,bindSessionModel:()=>RD,appendTurnAnchorChecked:()=>RZ,addReaction:()=>Q$,PROJECTS_ROOT:()=>PZ,MAX_UPLOAD_BYTES:()=>m8});import*as y8 from"@larksuiteoapi/node-sdk";import{execSync as jD}from"node:child_process";import{randomUUID as v8}from"node:crypto";import{mkdirSync as _Z,readFileSync as r1,statSync as EH,writeFileSync as SH}from"node:fs";import{readFile as qD}from"node:fs/promises";import{homedir as OH}from"node:os";import{basename as t1,extname as LD,isAbsolute as CH,join as jZ}from"node:path";import{sync as PD}from"cross-spawn";function qZ(){let $={};for(let[Z,J]of Z$)$[Z]=J;o(h7,$)}function DZ(){Z$.clear();try{let $=JSON.parse(r1(h7,"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"||!r$(Q.sessionName)||typeof Q.createdAt!=="number"||!Number.isFinite(Q.createdAt)){B(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}Z$.set(Z,{chatId:Z,sessionName:Q.sessionName,createdAt:Q.createdAt})}B(`feishu: loaded ${Z$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")B(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function FZ($,Z){if(!r$($))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 Z$.values())if(Y.sessionName===$&&Y.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Y.chatId}`);let J=Z$.get(Z),Q={sessionName:$,chatId:Z,createdAt:Date.now()};Z$.set(Z,Q);try{qZ()}catch(Y){if(J)Z$.set(Z,J);else Z$.delete(Z);throw Y}}function MZ($,Z){let J=Z$.get(Z);return J?.sessionName===$&&J.chatId===Z}function DD($){return p.projects[$]}function X4($){return YZ($,PZ,p.projects)}function M9($){return DH($,PZ,p.projects)}function d0($,Z){let J=F$(Z);return new y0(`${$} failed ${k(Z)}`,J.status,J.code,J.retryAfter,J.logId,J.message)}function U9($,Z={}){return X0($,{...Z,signal:Z.signal??AbortSignal.timeout(wH)})}async function yH($,Z,J){let Q=Z.signal??AbortSignal.timeout(wH);try{return await z$(await U9($,{...Z,signal:Q}),J)}catch(Y){if(Q.aborted&&Q.reason?.name==="TimeoutError")throw Q.reason;throw Y}}async function y$(){if(C8&&Date.now()<AH)return C8;return BZ??=(async()=>{let $=await yH("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:bH,app_secret:kH})},"tenant token");if(typeof $.tenant_access_token!=="string"||!$.tenant_access_token.trim())throw Error("feishu: tenant token MISS");return C8=$.tenant_access_token,AH=Date.now()+Math.max(0,($.expire??7200)-60)*1000,C8})().finally(()=>{BZ=null}),BZ}function UZ(){try{let $=JSON.parse(r1(w7,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")_0.set(Z,J);B(`feishu: loaded ${_0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function vH(){try{LZ()}catch($){B(`feishu: save session-chat-map failed: ${$}`)}}function LZ(){let $={};for(let[Z,J]of _0)$[Z]=J;o(w7,$)}function V4($,Z){if(_0.get($)===Z)return;let J=_0.get($);_0.set($,Z),vH(),B(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function b8($){let Z=_0.get($);if(!Z)return;_0.delete($),vH(),B(`feishu: unbound session "${$}" from ${Z}`)}function D9($,Z){let J=U0.get($)??{};J[Z.provider]=Z,U0.set($,J)}function NH($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Q=C$(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"||!CH(J.cwd))return null;return{provider:Q,sessionId:Y,cwd:J.cwd}}function RH($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if(!C$($.provider))throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!CH($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function MD($,Z,J){if(typeof $!=="string")return RH($);if(!Z)throw Error("cannot bind a conversation without a provider");return RH({provider:Z,sessionId:$,cwd:J??null})}function OZ(){try{let $=JSON.parse(r1(y7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");U0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){D9(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Q=J,Y=NH(Q);if(Y){D9(Z,Y);continue}for(let V of W5){let X=Q[V];if(typeof X==="string"&&X.trim()){D9(Z,{provider:V,sessionId:X.trim(),cwd:null});continue}let H=NH(X,V);if(H)D9(Z,H)}}B(`feishu: loaded ${U0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")B(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function k8(){let $={};for(let[Z,J]of U0){let Q={};if(J.codex)Q.codex={...J.codex};if(J.claude)Q.claude={...J.claude};if(J.dsh)Q.dsh={...J.dsh};$[Z]=Q}o(y7,$)}function O9($,Z,J,Q){let Y=MD(Z,J,Q),V=U0.get($),X=V?{...V}:void 0,H=V?.[Y.provider];if(H?.sessionId===Y.sessionId&&H.cwd===Y.cwd)return;D9($,Y);try{k8()}catch(z){if(X)U0.set($,X);else U0.delete($);throw z}}function A1($,Z="codex"){let J=U0.get($)?.[Z];return J?{...J}:null}function H4($,Z){let J=U0.get($);if(!J||Z&&J[Z]===void 0)return;let Q={...J};if(!Z)U0.delete($);else{let Y={...J};if(delete Y[Z],!Y.codex&&!Y.claude)U0.delete($);else U0.set($,Y)}try{k8()}catch(Y){throw U0.set($,Q),Y}}function fH($){if(!$||typeof $!=="object")return null;let Z=$;if(!C$(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 hH($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Q=fH(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 IH($){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=fH(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=hH(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 UD($){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 OD($,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=hH(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:UD(J.writes)}}function AD($){if(!$||typeof $!=="object")return null;let Z=$,J=IH(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 AZ($){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(r1(v7,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");Z0.clear();let Z=0,J=0;for(let[Q,Y]of Object.entries($)){let V,X,H=null;if(Array.isArray(Y))V=Y,X=null;else if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let K=Y;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(V=K.anchors,K.base===null)X=null;else{let _=IH(K.base);if(!_){J++;continue}X=_}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let _=AD(K.pendingLaunch);if(!_){J++;continue}H=_}}else{J++;continue}let z=U0.get(Q),G=z?.claude!==void 0&&z.codex===void 0?"claude":null,W=[];for(let K of V){let _=OD(K,G);if(_)W.push(_);else J++}if(W.length||X!==null||H)Z0.set(Q,{base:X,anchors:W,...H?{pendingLaunch:H}:{}}),Z+=W.length}if(B(`feishu: loaded ${Z} turn anchors across ${Z0.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 F9(){let $={};for(let[Z,J]of Z0)$[Z]=J;o(v7,$)}function RZ($,Z){let J=Z0.get($),Q=[...J?.anchors??[],Z],Y=J?.base??null;if(Q.length>TH){let V=Q.splice(0,Q.length-TH),X=V[V.length-1].checkpoint;Y={kind:"fork",source:X.source,through:X}}Z0.set($,{base:Y,anchors:Q,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{F9()}catch(V){if(J)Z0.set($,J);else Z0.delete($);throw V}}function z4($){return Z0.get($)?.anchors??[]}function G4($){return Z0.get($)?.base??null}function W4($){let Z=Z0.get($)?.pendingLaunch;return Z?AZ(Z):null}function N1($,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=Z0.get($),Q=J?.base??null,Y=J?.anchors.slice()??[];if(!Z&&Y.length===0&&Q===null)Z0.delete($);else Z0.set($,{base:Q,anchors:Y,...Z?{pendingLaunch:AZ(Z)}:{}});try{F9()}catch(V){if(J)Z0.set($,J);else Z0.delete($);throw V}}function J$($,Z,J,Q){let Y=Z0.get($),V=Q===void 0?Y?.pendingLaunch:Q??void 0,X=V?AZ(V):void 0;if(Z.length===0&&J===null&&!X)Z0.delete($);else Z0.set($,{base:J,anchors:Z.slice(),...X?{pendingLaunch:X}:{}});try{F9()}catch(H){if(Y)Z0.set($,Y);else Z0.delete($);throw H}}function r$($){return xH.test($)?$.replace(xH,""):null}function TZ($,Z=[]){let J=new Date,Q=(H)=>String(H).padStart(2,"0"),Y=`${Q(J.getMonth()+1)}${Q(J.getDate())}-${Q(J.getHours())}${Q(J.getMinutes())}`,V=new Set([...j0.values(),...Z0.keys(),...Z]),X=`${$}*${Y}`;for(let H=2;V.has(X);H++)X=`${$}*${Y}-${H}`;return X}function xZ(){try{let $=JSON.parse(r1(f7,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){I0.set(Z,{provider:m2(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Q,provider:Y}=J,V=C$(Y)?Y:typeof Q==="string"&&Q.trim()?m2(Q):"claude",X=typeof Q==="string"&&Q.trim()?Q:null;if(V==="claude"&&!X)continue;let{effort:H,tokenSourceId:z}=J,G=typeof z==="string"&&z.trim()?z.trim():null,W=V==="dsh"?F0(H)?H:null:V==="claude"?A0(H)?H:null:W$(H)?H: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 ND(){try{w8()}catch($){B(`feishu: save session-model-map failed: ${$}`)}}function w8(){let $={};for(let[Z,J]of I0)$[Z]=J;o(f7,$)}function RD($,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}:{}}),ND()}function R1($,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{w8()}catch(H){if(V)I0.set($,V);else I0.delete($);throw H}}function EZ($){let Z=I0.get($);if(Z)return Z;let J=r$($);return J?I0.get(J)??null:null}function SZ($){let Z=_0.get($),J=U0.get($),Q=I0.get($),Y=Z0.get($),V=[...Z$.entries()].filter(([,X])=>X.sessionName===$);_0.delete($),U0.delete($),I0.delete($),Z0.delete($);for(let[X]of V)Z$.delete(X);try{LZ(),k8(),w8(),F9(),qZ()}catch(X){if(Z)_0.set($,Z);if(J)U0.set($,J);if(Q)I0.set($,Q);if(Y)Z0.set($,Y);for(let[z,G]of V)Z$.set(z,G);let H=[X];for(let z of[LZ,k8,w8,F9,qZ])try{z()}catch(G){H.push(G)}throw H.length===1?H[0]:AggregateError(H,`failed to clear and restore conversation state for ${$}`)}}function CZ($){o(g7,$)}function bZ(){let $;try{$=r1(g7,"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 f8($){let Z=_0.get($);if(Z){let Q=j0.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 j0)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 A9(){try{let $;do{let Z=await W0.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});if(Z.code&&Z.code!==0)throw d0("feishu chat.list",Z);for(let J of Z.data?.items??[])if(J.chat_id&&J.name)j0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);B(`feishu: refreshed chat list — ${j0.size} groups`)}catch($){B(`feishu: refresh chat list failed: ${$}`)}}async function h8(){let $=new Map,Z;do{let J=await W0.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw d0("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;j0.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 I8($){let Z=_0.get($);if(Z&&j0.get(Z)===$){let V=await gH(Z);if(V.name===$&&mH(V.status))return Z;j0.delete(Z),b8($)}let Q=(await h8()).get($)??[];if(Q.length===0)return null;let Y=_0.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 kZ($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await I8($);if(J){let V=await TD(J,Z);return V4($,J),{chatId:J,created:!1,joined:V}}let Q=await W0.im.chat.create({params:{user_id_type:"open_id",uuid:v8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw d0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return j0.set(Y,$),V4($,Y),{chatId:Y,created:!0,joined:!0}}async function wZ($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await I8($))throw Error(`temporary group name already exists: ${$}`);let Q=await W0.im.chat.create({params:{user_id_type:"open_id",uuid:v8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Q.code&&Q.code!==0)throw d0("feishu chat.create",Q);let Y=Q.data?.chat_id;if(!Y)throw Error("feishu chat.create returned no chat_id");return j0.set(Y,$),V4($,Y),{chatId:Y,created:!0,joined:!0}}async function yZ($){let Z=await I8($);if(!Z)return b8($),{chatId:null,disbanded:!1};let J=await W0.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw d0("feishu chat.delete",J);if(j0.delete(Z),_0.get($)===Z)b8($);return{chatId:Z,disbanded:!0}}async function vZ($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await gH(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!mH(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Q=await W0.im.chat.delete({path:{chat_id:Z}});if(Q.code&&Q.code!==0)throw d0("feishu chat.delete",Q);return j0.delete(Z),{chatId:Z,disbanded:!0}}async function TD($,Z){let J;do{let Y=await W0.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 d0("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 W0.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Q.code&&Q.code!==0)throw d0("feishu chatMembers.create",Q);return!0}async function fZ($){try{let Z=await y$(),J=await U9(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}}),Y=(await z$(J,`fetchChatName ${$}`)).data?.name;if(typeof Y==="string"&&Y)return j0.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 g8($,Z,J,Q,Y){let V=v8();try{return await p1(`send${$} chat=${Z}`,async()=>{let X=await W0.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 d0(`send${$}`,X);let H=X?.data?.message_id;if(typeof H!=="string"||!H.trim())throw Error(`send${$} message_id MISS`);return H})}catch(X){return Y?.(X),null}}async function gH($){let Z=await W0.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw d0("feishu chat.get",Z);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function mH($){return $===null||$==="normal"}async function b($,Z,J){return U$($,()=>g8("Text",$,"text",JSON.stringify({text:Z}),J))}async function i($,Z,J){return U$($,()=>g8("Card",$,"interactive",JSON.stringify(U1(Z)),J))}async function hZ($){let Z=await W0.im.message.list({params:{container_id_type:"chat",container_id:$,sort_type:"ByCreateTimeDesc",page_size:1}});if(Z.code!==0)throw d0("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 K4($,Z){let J=await W0.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(U1(Z))}});if(J?.code!==0)throw d0("feishu message.patch",J)}async function g($,Z){return U$($,()=>xD($,Z))}async function xD($,Z){try{let J=await y$(),Q=await U9("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 z$(Q,`sendTextRaw chat=${$}`)).data?.message_id??null}catch(J){return B(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function Q$($,Z){if(!$)return null;try{let J=await W0.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}});if(J?.code&&J.code!==0)throw d0("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 W0.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}});if(J?.code&&J.code!==0)throw d0("feishu messageReaction.delete",J)}catch(J){B(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function e1($,Z){if(!$){B("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){B(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await y$(),Q=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let Y=await U9(Q,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})}),X=(await z$(Y,`urgentApp ${$}`)).data?.invalid_user_id_list??[],H=Z.length-X.length;B(`feishu: urgentApp ${$} ok — delivered=${H}${X.length?` invalid=${X.length}`:""}`)}catch(Y){B(`feishu: urgentApp ${$} failed: ${Y}`)}}async function N9($,Z,J,Q){try{let Y=await y$(),V=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,X=await U9(V,{headers:{Authorization:`Bearer ${Y}`}});if(!X.ok)await z$(X,`download ${J}`);let H=Buffer.from(await X.arrayBuffer());_Z(m7,{recursive:!0});let z=Q?Q.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,G=jZ(m7,`${Date.now()}-${v8()}-${z}`);return SH(G,H,{flag:"wx"}),B(`feishu: downloaded ${J} ${G} (${H.length}B)`),G}catch(Y){B(`feishu: download ${J} failed: ${Y instanceof Error?Y.message:Y}`);return}}function SD($){return ED.has(LD($).toLowerCase())}async function pH($,Z){let J=`upload${Z==="image"?"Image":"File"}`,Q;return p1(`${J} ${$}`,async()=>{if(Q??=new Blob([Uint8Array.from(await qD($))]),Q.size>m8)throw Error(`${t1($)} 超过 30 MB`);let Y=await y$(),V=new FormData;if(Z==="image")V.append("image_type","message");else V.append("file_type","stream"),V.append("file_name",t1($));V.append(Z,Q,t1($));let H=(await yH(`https://open.feishu.cn/open-apis/im/v1/${Z}s`,{method:"POST",headers:{Authorization:`Bearer ${Y}`},body:V},J)).data?.[`${Z}_key`];if(typeof H!=="string"||!H.trim())throw Error(`${J} ${Z}_key MISS`);return H})}async function IZ($,Z){try{let J=EH($);if(!J.isFile())return B(`feishu: uploadImageKey not a file — ${$}`),Z?.(Error("路径不是普通文件")),null;if(J.size>m8)return B(`feishu: uploadImageKey oversize — ${$} (${(J.size/1024/1024).toFixed(1)} MB)`),Z?.(Error(`${t1($)} 超过 30 MB`)),null}catch(J){return B(`feishu: uploadImageKey stat failed — ${$}: ${J}`),Z?.(J),null}try{return await pH($,"image")}catch(J){return Z?.(J),null}}async function p8($,Z,J){return U$($,()=>g8("Image",$,"image",JSON.stringify({image_key:Z}),J))}async function cH($,Z,J){return U$($,()=>g8("File",$,"file",JSON.stringify({file_key:Z}),J))}async function R9($,Z){try{let Y=EH(Z);if(!Y.isFile())return B(`feishu: uploadAndSend not a file — ${Z}`),await b($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>m8)return B(`feishu: uploadAndSend oversize — ${Z} (${Y.size}B)`),await b($,`❌ 出站文件: ${t1(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=SD(Z)?"image":"file",Q=J==="image"?"出站图片":"出站文件";try{let Y=await pH(Z,J),V,X=(z)=>{V=z},H=await(J==="image"?p8($,Y,X):cH($,Y,X));if(!H)return B(`feishu: uploadAndSend ${Z} send failed after upload`),await b($,`❌ ${Q}发送失败: ${t1(Z)}(上传已完成)
109
109
  ${k(V)}`),!1;return B(`feishu: uploadAndSend ${Z} delivered msg=${H}`),!0}catch(Y){return B(`feishu: uploadAndSend ${Z} failed: ${Y}`),await b($,`❌ ${Q}上传失败: ${t1(Z)} — ${k(Y)}`),!1}}function gZ($){_Z($,{recursive:!0}),B(`feishu: provisioned ${$}`);let Z=jZ(OH(),".codex","config.toml");try{_Z(jZ(OH(),".codex"),{recursive:!0});let J="";try{J=r1(Z,"utf8")}catch{}let Q=`[projects.${JSON.stringify($)}]`;if(!J.includes(Q)){let Y=J.trimEnd();J=`${Y}${Y?`
110
110
 
111
111
  `:""}${Q}
112
112
  trust_level = "trusted"
113
113
  `,SH(Z,J)}}catch(J){B(`feishu: codex trust write failed for ${$}: ${J}`)}try{jD("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function T9($=c){let Z=PD(J9(),["login","status",...v.cliArgs($)],{timeout:1e4,shell:!1,encoding:"utf8",env:v.env($,{...process.env,...p.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}
114
- ${Z.stderr}`)}function mZ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var bH,kH,PZ,Z$,O1=async($)=>{try{let Z=await y8.defaultHttpInstance.request({...$,$return_headers:!0}),J=F$({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=F$(Z);Z.message=k(Z),Object.assign(Z,{apiMessage:J.message,logId:J.logId})}throw Z}},FD,W0,wH=15000,C8="",AH=0,BZ=null,j0,_0,M0,Z0,TH=200,xH,I0,m8=31457280,ED;var e=R(()=>{o0();b2();t5();B0();f0();j1();B0();V0();I();D0();v0();E8();h0();u1();MH();bH=p.feishu.app_id,kH=p.feishu.app_secret,PZ=p.runtime.projects_root,Z$=new Map;FD={request:O1,get:($,Z)=>O1({...Z,url:$,method:"GET"}),delete:($,Z)=>O1({...Z,url:$,method:"DELETE"}),head:($,Z)=>O1({...Z,url:$,method:"HEAD"}),options:($,Z)=>O1({...Z,url:$,method:"OPTIONS"}),post:($,Z,J)=>O1({...J,url:$,data:Z,method:"POST"}),put:($,Z,J)=>O1({...J,url:$,data:Z,method:"PUT"}),patch:($,Z,J)=>O1({...J,url:$,data:Z,method:"PATCH"})},W0=new y8.Client({appId:bH,appSecret:kH,disableTokenCache:!1,httpInstance:FD});j0=new Map,_0=new Map;M0=new Map;Z0=new Map;xH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;I0=new Map;ED=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});async function lH($=(Z)=>new t$({accountId:Z})){if(g2(c))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Q;try{Z=$(c),await Z.initialize("lodestar-login-check"),Q=await P1(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Y){J=Error(`默认账号登录检查失败:${B4(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,`默认账号检查进程关闭失败:${B4(Y).message}`].filter(Boolean).join(";"),{cause:Y})}if(J)throw J}class uH{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Y)=>new t$({accountId:Y,login:!0}),Z=900000,J=(Y,V)=>{v.recordLogin(Y,V),L1(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=lV($),Q;try{Q=this.createClient($)}catch(z){throw J(),z}let Y,V,X=new Promise((z,G)=>{Y=z,V=G});X.catch(()=>{});let H={owner:Z,client:Q,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:X,resolve:Y,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};H.notification=(z,G)=>{if(H.finishing||!H.loginRequested)return;if(z==="account/updated"){if(G?.authMode==="chatgpt"){if(H.authUpdated=!0,H.loginSucceeded)this.finish(H)}return}if(z!=="account/login/completed")return;if(!H.loginId){H.early.push(G);return}if(G?.loginId!==H.loginId)return;if(G?.success!==!0){this.finish(H,Error(typeof G?.error==="string"?G.error:"Codex 登录未成功"));return}if(H.loginSucceeded)return;if(H.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${H.authUpdated}`),H.timer)clearTimeout(H.timer);if(H.authUpdated)this.finish(H);else H.timer=setTimeout(()=>{this.finish(H,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},H.closed=(z)=>{this.finish(H,z)},Q.on("notification",H.notification),Q.on("closed",H.closed),Q.on("protocolError",H.closed),this.attempts.set($,H);try{await Q.initialize("lodestar-login"),H.loginRequested=!0;let z=await Q.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(z?.type!=="chatgptDeviceCode"||typeof z.loginId!=="string"||!z.loginId||typeof z.userCode!=="string"||!z.userCode||typeof z.verificationUrl!=="string"||new URL(z.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(H.loginId=z.loginId,H.finishing)throw await X,Error("登录已结束");H.timer=setTimeout(()=>{this.cancelAttempt(H,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let G of H.early)H.notification("account/login/completed",G);return H.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:X}}catch(z){return await this.finish(H,B4(z)),await X}}pending($){return[...this.attempts.values()].filter((Z)=>Z.owner.chatId===$.chatId&&Z.owner.userOpenId===$.userOpenId).map((Z)=>Z.accountId)}async cancel($,Z){let J=this.attempts.get($);if(!J)throw Error("该账号没有等待中的登录");if(!Z.userOpenId||Z.chatId!==J.owner.chatId||Z.userOpenId!==J.owner.userOpenId)throw Error("只有发起登录的用户可在原群取消");if(J.finishing)throw Error("登录正在收尾,请等待结果");await this.cancelAttempt(J,"登录已取消")}async cancelAttempt($,Z){if($.finishing)return;$.finishing=!0;let J=Error(Z);if($.loginId&&$.client.isAlive())try{await $.client.request("account/login/cancel",{loginId:$.loginId})}catch(Q){J=Error(`${Z};取消请求失败:${B4(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=B4(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,`登录进程关闭失败:${B4(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 B4($){return $ instanceof Error?$:Error(String($))}var $2;var pZ=R(()=>{U$();D0();I();$2=new uH});import{readFileSync as CD}from"node:fs";import{homedir as bD}from"node:os";import{join as aH}from"node:path";function wD(){return process.env.CLAUDE_CONFIG_DIR||aH(bD(),".claude")}function cZ(){try{let $=CD(aH(wD(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function Z2($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function yD($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function vD($){let Z=yD($);return Z&&Z2($)?Z:null}function iH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function nH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function fD($){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:iH(W.percentage),resetsAt:nH(W.nextResetTime)}:null,H=X(Q),z=X(Y),G=V?{percent:iH(V.percentage),resetsAt:nH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!H&&!z&&!G)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:H,weekly:z,monthly:G,fetchedAt:Date.now()}}async function c8($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:cZ(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let V=vD(Y);if(!V)return{state:"not_glm",baseUrl:Y||void 0};return kD.readStale(K$("glm",V,Q),()=>hD(V,Q))}async function hD($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Q=new AbortController,Y=setTimeout(()=>Q.abort(),dH);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:b$(V.headers)};let X=await V.json(),H=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||H!==void 0&&String(H)!=="200"){let W=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[H===void 0?"":`code ${H}`,W===void 0?"":String(W)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(H)==="429"?"rate_limited":"network",reason:K,retryAfterMs:b$(V.headers)}}let z=X?.data??X,G=fD(z);if(G.state==="network")B(`glm-usage: quota/limit MISS: ${G.reason}`);return G}catch(V){let X=(V?.name==="AbortError"?`timeout ${dH}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 dH=1e4,kD;var l8=R(()=>{o0();I();s$();kD=new $$});function f$($){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 _4($){let Z=f$($),J=new URL(Z);return J.protocol==="https:"&&!J.port&&J.pathname==="/"&&["cf.api.fan","slb-v1.api.fan","www.packyapi.ai"].includes(J.hostname)?ID:Z}function lZ($,Z){let J=f$($),Q=K$("packy-models",J,Z),Y=u8.get(Q);if(Y)return Y;let V=S$(`${J}/v1/models`,Z,"PackyAPI models").then((X)=>{let H=new Set;return X.map((z)=>{if(typeof z.id!=="string"||!z.id.trim()||H.has(z.id)||!Array.isArray(z.supported_endpoint_types)||!z.supported_endpoint_types.length||!z.supported_endpoint_types.every((G)=>typeof G==="string"&&G))throw Error("PackyAPI 模型目录缺少有效 id/协议声明,或含重复模型");return H.add(z.id),{id:z.id,display:typeof z.name==="string"&&z.name?z.name:z.id,protocols:[...z.supported_endpoint_types],...v$(z.reasoning)?{reasoning:z.reasoning}:{}}})}).finally(()=>{if(u8.get(Q)===V)u8.delete(Q)});return u8.set(Q,V),V}function v$($){return $!==null&&typeof $==="object"&&!Array.isArray($)}async function i8($,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 e$(Q.status,"响应不是有效 JSON",b$(Q.headers))}let X=v$(V)?V.code:void 0,H=X!==void 0&&![!0,0,200,"0","200"].some((z)=>z===X);if(!Q.ok||!v$(V)||V.success===!1||H||V.error!=null){let z=v$(V)&&v$(V.error)?V.error.message:v$(V)?V.message:null;throw new e$(Q.status,typeof z==="string"?z:"上游接口返回错误",b$(Q.headers))}return V}async function uZ($,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=f$($),V=K$("packy-balance",Y,JSON.stringify([J,Z])),X=async()=>{try{let z=await i8(`${Y}/api/user/self`,Z,{"New-Api-User":J}),G=z.data;if(z.success!==!0||!v$(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 i8(`${Y}/api/status`)).data;if(!v$(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(z){let G=p0(z,[Z]);return B(`PackyAPI balance MISS: ${G}`),{state:z instanceof e$&&[401,403].includes(z.status)?"no_credentials":z instanceof e$&&z.status===429?"rate_limited":"network",kind:"balance",windows:[],reason:G,...z instanceof e$&&z.retryAfterMs!==void 0?{retryAfterMs:z.retryAfterMs}:{}}}};if(!Q)return d8.readStale(V,X);let H=await X();if(H.state==="ok")d8.prime(V,H);else d8.invalidate(V);return H}async function oH($,Z){if(!Z)return{state:"no_credentials",kind:"quota",windows:[]};let J=_4($);return d8.readStale(K$("packy",J,Z),async()=>{try{let Y=(await i8(`${J}/api/usage/token/`,Z)).data;if(!v$(Y)||typeof Y.unlimited_quota!=="boolean")throw Error("PackyAPI 令牌配额响应缺少 unlimited_quota");if(Y.unlimited_quota)return{state:"not_applicable",kind:"balance",windows:[],reason:"此 API key 为无限额度令牌;令牌接口不提供账户余额,需要系统访问令牌查询。"};let{total_available:V,total_granted:X}=Y;if(typeof V!=="number"||!Number.isFinite(V)||typeof X!=="number"||!Number.isFinite(X)||X<0)throw Error("PackyAPI 令牌配额数值缺失或无效");let H=(await i8(`${J}/api/status`)).data;if(!v$(H)||typeof H.quota_per_unit!=="number"||!Number.isFinite(H.quota_per_unit)||H.quota_per_unit<=0||H.quota_display_type!=="USD")throw Error("PackyAPI 配额单位缺失或不是已支持的 USD 额度单位");return{state:"ok",kind:"quota",windows:[],fetchedAt:Date.now(),quota:{remaining:V/H.quota_per_unit,limit:X/H.quota_per_unit,currency:"USD"}}}catch(Q){let Y=p0(Q,[Z]);return B(`PackyAPI quota MISS: ${Y}`),{state:Q instanceof e$&&[401,403].includes(Q.status)?"no_credentials":Q instanceof e$&&Q.status===429?"rate_limited":"network",kind:"quota",windows:[],reason:Y,...Q instanceof e$&&Q.retryAfterMs!==void 0?{retryAfterMs:Q.retryAfterMs}:{}}}})}var J2="https://cf.api.fan",ID="https://www.packyapi.ai",u8,e$,d8;var dZ=R(()=>{o0();k2();s$();I();u8=new Map;e$=class e$ extends Error{status;retryAfterMs;constructor($,Z,J){super(`PackyAPI HTTP ${$}: ${Z}`);this.status=$;this.retryAfterMs=J}};d8=new $$});function sH($){return o8.find((Z)=>Z.other===$)?.id??$}function tH($){let Z=o8.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function x9($){let Z=$.api_key?.trim(),J=$.auth_token?.trim();if(Z&&J&&Z!==J)throw Error("同一账号的 api_key 与 auth_token 不一致,请重新配置");return Z||J}function a8($,Z){if($.id==="packy")return f$(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 u4(`${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 n8($,Z){let J=a8($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function j4($){let{api_key:Z,auth_token:J,base_url:Q,...Y}=$;return Y}function iZ($,Z,J={}){let Q=Z[$.id]??{},Y=Z[$.other]??{},V=x9(Q),X=x9(Y),H=Q.base_url?.trim(),z=Y.base_url?.trim();if(V&&X&&V!==X||H&&z&&n8($,H)!==n8($,z))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:a8($,H||z||$.base)};let G=J[$.id]??J[$.other]??{};if(x9(G)&&(H||z)&&G.base_url&&n8($,H||z)!==n8($,G.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:x9(G),base:a8($,H||z||G.base_url||$.base)}}function E9($,Z={}){let J={...$};for(let Q of o8){let{key:Y,base:V}=iZ(Q,$,Z);J[Q.id]={...j4($[Q.id]??{}),base_url:V,...Q.id==="glm"?{auth_token:Y??""}:{api_key:Y??""}},J[Q.other]={...j4($[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 gD(J),J}function gD($){let Z=new Set(["packy","packy-secondary","packy-codex"]),J=new Set,Q=new Set,Y=(X)=>!!(X.management_token?.trim()||X.management_user_id?.trim()||X.management_url?.trim()),V=(X)=>{if(Q.has(X))throw Error(`PackyAPI 余额账号引用循环:${X}`);if(J.has(X))return $[X];Q.add(X);let H=$[X]??{},z=H.billing_source?.trim(),G=z||(X==="packy-codex"&&!Y(H)?"packy":void 0);if(G){if(!Z.has(G)||!$[G])throw Error(`PackyAPI 余额账号引用不存在:${G}`);if(z&&Y(H))throw Error(`PackyAPI ${X} 不能同时配置 billing_source 和独立余额凭据`);let W=V(G);$[X]={...H,...z||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||_4(W.base_url||J2)}:{}}}return Q.delete(X),J.add(X),$[X]??H};for(let X of Z)if($[X])V(X)}function nZ($,Z,J){let Q=Object.fromEntries(Object.entries(J).filter(([,z])=>z!==void 0)),Y={...$,[Z]:{...$[Z],...Q}},V=o8.find((z)=>z.id===Z||z.other===Z);if(!V)return{[Z]:Y[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,H=J.base_url!==void 0;if(X||H){let z=$[Z]??{},G=$[V.id]??{},W=$[V.other]??{},K=X?x9(J):iZ(V,$).key,_=a8(V,J.base_url?.trim()||z.base_url||G.base_url||W.base_url||V.base);Y[V.id]={...j4(Y[V.id]??{}),base_url:_,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Y[V.other]=j4(Y[V.other]??{})}else{let{key:z,base:G}=iZ(V,Y);Y[V.id]={...j4(Y[V.id]??{}),base_url:G,...V.id==="glm"?{auth_token:z??""}:{api_key:z??""}},Y[V.other]=j4(Y[V.other]??{})}return{[V.id]:Y[V.id],[V.other]:Y[V.other]}}var o8;var S9=R(()=>{d4();dZ();o8=[{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 pD($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function s8($,Z,J){try{let Q=await X0(pD($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(mD)});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 mD=15000;var aZ=R(()=>{o0();I()});function rH($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function cD($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function eH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function lD($){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 uD($){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 oZ($){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(rH($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(rH($.weekly,"weekly","周额度"));if($.monthly)Z.push(cD($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var sZ=R(()=>{Q0();l8();Z4();B9();aZ();I();d4();L0({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)&&Z2(J),V=$.model?.trim()||void 0,X=uD($.slots),H={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await tX(J,Q),W=[...new Set([...eH($.models),...eH($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:$4,defaultEffort:"max",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=lD(H.models.map((K)=>K.model));for(let K of H.models){let _=t2("glm",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`glm refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...l0(z)};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(z){return j8("glm",z)},async verifyModel(z){return s8(J,{Authorization:`Bearer ${Q}`},z)},async readUsage(){return oZ(await c8(J,Q))}};return H},setup:{commandSuffix:"glm",hint:($)=>`配置 ${$}:发送 \`glm-setup <api_key>\`(智谱国内站),或 \`glm-setup <base_url> <api_key>\`(指定平台)。Claude Code 和 DeepSeek Harness 共用该账号;校验失败保留原配置。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:glm-setup <api_key>,或 glm-setup <base_url> <api_key>;只填写 Key 本身,不加 Bearer 前缀。"};try{return{config:{agent:"claude",base_url:u4(Z.length===2?Z[0]:w2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await y2($.base_url??w2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!Z2(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var $z=R(()=>{Q0();Z4();L0({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 U8(),!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 dD}from"node:os";function r8($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function t8($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!r8($))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 Jz($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function Qz($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=Jz(G9(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&&Jz(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 nD($){if(!r8($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!r8($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[t8(Z.five_hour,"fiveHour","5h 窗口"),t8(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(t8(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(!r8(Y)||typeof Y.display_name!=="string"||!Y.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Y.display_name.trim();J.push(t8(Y,`modelWeekly:${V}`,`${V} 周额度`)),Q=!0}}if(!Q)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function Yz($){return iD.readStale("claude-subscription",()=>aD($))}async function aD($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (e2(),i5)),J=new Z({workDir:dD(),effort:"default",allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(V)=>B(`Claude subscription usage MISS: ${V.message}`));let Q,Y;try{let V=await Promise.race([J.readSubscriptionUsage(),new Promise((X,H)=>{Q=setTimeout(()=>H(Error(`Claude 订阅额度查询超时(${Zz/1000}s)`)),Zz)})]);return nD(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":n2(Z)?"rate_limited":"network",windows:[],reason:J}}}var Zz=30000,iD;var tZ=R(()=>{I();I5();s$();iD=new $$});function oD(){let $=Object.fromEntries(_8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function sD($){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 Vz=R(()=>{B0();I();Q0();Z4();tZ();o$();L0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=oD(),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:sD,spawnEnv(X){return{...l0(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 U8({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id});if(!X.length)throw Error("Claude Code 订阅模型目录为空");let H=[...s($.custom_models),...s($.models)];if(J&&!X.some((z)=>z.model===J)&&!H.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let z=X.find((G)=>G.model===(J??X[0].model));if(!A0($.effort)||z&&!z.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(z)z.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let H=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${H}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:H}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Y??=Yz({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Y=void 0}),Y}};return V}})});function Hz($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function tD($){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 rD($){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 eD($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function zz($,Z){return(await rZ(new URL($).origin,Z)).map((Q)=>({model:Q,display:Q,efforts:$4,defaultEffort:"high"}))}async function rZ($,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 S$(`${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 eZ($,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 ZF.readStale(K$("deepseek",J,Z),()=>JF(J,Z))}async function JF($,Z){try{let J=await X0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout($F)});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:b$(J.headers)};let Q=await J.json(),V=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",H=V?.total_balance;if(!X||typeof H!=="string"&&typeof H!=="number"||String(H).trim()===""||!Number.isFinite(Number(H)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(H),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var Xz="https://api.deepseek.com/anthropic",$F=1e4,ZF;var $J=R(()=>{o0();Q0();Z4();B9();aZ();I();k2();s$();ZF=new $$;L0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||Xz,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,V=$.model?.trim()||void 0,X=rD($.slots),H={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await zz(J,Q),W=[...new Set([...Hz($.models),...Hz($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:$4,defaultEffort:"high",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=tD(H.models.map((K)=>K.model));for(let K of H.models){let _=t2("deepseek",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`deepseek refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...l0(z)};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(z){return j8("deepseek",z)},async verifyModel(z){return s8(J,{"x-api-key":Q},z)},async readUsage(){if(!Q)return{kind:"balance",state:"no_credentials",windows:[]};return eZ(J,Q)}};return H},setup:{commandSuffix:"deepseek",hint:($)=>`配置 ${$}:发送 \`deepseek-setup <api_key>\`;Claude Code 和 DeepSeek Harness 共用该账号。自建端点用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Q=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Q}}},async validate($){await zz($.base_url??Xz,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!eD(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function Q2($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var ZJ;var Gz=R(()=>{ZJ=[{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 Y2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function QJ($){return $ instanceof Error?$.message:String($)}function Kz($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function q4($){return $.replace(/\[1m\]$/,"")}function L4($){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 VF($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Q=await X0(`${L4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(QF)});if(!Q.ok){let Y=await Q.text(),V="";if(Y.trim().startsWith("{"))try{let X=JSON.parse(Y);if(Y2(X)&&Y2(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new e8(Q.status,V.replaceAll(Z,"[redacted]"),b$(Q.headers))}return Q.json()}async function Bz($,Z){let J=await S$(`${L4($)}/v1/models/user`,Z,"OpenRouter models"),Q=[],Y=new Set;for(let V of J){if(!Y2(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!Y2(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(Q2(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Y.has(V.id))continue;let X=Y2(V.reasoning)?V.reasoning:void 0,H=X?.supported_efforts,z=H===null||H===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(H)?[...new Set(H.filter((_)=>_!=="default"&&A0(_)))]:["default"],G=ZJ.find((_)=>_.model===V.id),W=G?z.includes(G.effort)?G.effort:null:z[0]==="default"?"default":A0(X?.default_effort)&&z.includes(X.default_effort)?X.default_effort:null,K=t2("openrouter",V.id);Q.push({model:V.id,display:V.name,efforts:z,defaultEffort:W,context1m:K!==void 0&&K>=1e6||void 0}),Y.add(V.id)}if(!Q.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Q}function _z($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function XF($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return YF.readStale(K$("openrouter",L4($),Z),()=>HF($,Z))}async function HF($,Z){try{let J=await VF($,Z,"credits");if(!Y2(J)||!Y2(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Q,total_usage:Y}=J.data;if(!_z(Q)||!_z(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=QJ(J);return B(`openrouter readUsage MISS: ${Q}`),{kind:"balance",state:J instanceof e8&&J.status===429?"rate_limited":"network",windows:[],reason:Q,...J instanceof e8?{retryAfterMs:J.retryAfterMs}:{}}}}var Wz="https://openrouter.ai/api",QF=1e4,YF,JJ,e8;var jz=R(()=>{o0();B0();Q0();B9();I();Gz();k2();s$();YF=new $$,JJ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};e8=class e8 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};L0({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()||Wz,V=$.model?.trim()||"",X=$.models===void 0?ZJ.map((z)=>z.model):Kz($.models),H={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Q,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(z){if(Q2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let G=H.modelSelection.availableModels.find((W)=>q4(W.model)===q4(z));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(H.models=[],H.modelSelection.availableModels=[],!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await Bz(Y,Q),G=z.find((K)=>K.model===q4(V));if(V&&!G)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!A0($.effort)||!G.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);G.defaultEffort=$.effort}let W=X.map((K)=>{let _=z.find((j)=>j.model===q4(K));if(!_)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:Q2(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:K}});H.models=W,H.modelSelection.availableModels=z,H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let G=QJ(z);B(`openrouter refreshModels MISS: ${G}`),H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G}}},spawnEnv(z,G){if(!Q)throw Error("OpenRouter API key missing");let W=G||V;if(!W)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(Q2(W))throw Error(`OpenRouter 已排除此厂商或自动路由: ${W}`);let K=l0(z);K.ANTHROPIC_BASE_URL=L4(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 _ of Object.values(JJ))K[_]=W;for(let _ of Kz($.slots)){let j=_.indexOf("="),L=_.slice(0,j).trim(),q=_.slice(j+1).trim();if(j<1||!Object.hasOwn(JJ,L)||!q)throw Error(`OpenRouter slots 无效: ${_}`);if(Q2(q)||!H.modelSelection.availableModels.some((D)=>!D.unavailableReason&&q4(D.model)===q4(q)))throw Error(`OpenRouter slot 模型不在账号目录中: ${q}`);if(H.modelEnvironmentRevision(q)!==H.modelEnvironmentRevision(W))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${q}`);K[JJ[L]]=q}return K},resolveSpawnModel(z){if(Q2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return XF(Y,Q)}};return H},setup:{commandSuffix:"openrouter",hint:($)=>`启用 ${$}:发送 \`openrouter-setup <api_key>\`,然后通过 \`model\` 选择模型。自建端点用 \`openrouter-setup <base_url> <api_key>\`。`,parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||Z.length===1&&/^https?:\/\//i.test(Z[0]))return{error:"用法: openrouter-setup <api_key> 或 openrouter-setup <base_url> <api_key>"};try{return{config:{agent:"claude",api_key:Z[Z.length-1],...Z.length===2?{base_url:L4(Z[0])}:{}}}}catch(J){return{error:QJ(J)}}},async validate($){await Bz($.base_url??Wz,$.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=L4(Z);if(new URL(Q).hostname!=="openrouter.ai")return null;return{base_url:Q,api_key:J}}catch{return null}}}})});function GF($){return $.trim().replace(/\[1m\]$/,"").toLowerCase().split("/").at(-1)??""}function Lz($,Z="packy"){return zF[Z].includes(GF($))}var qz,zF;var Pz=R(()=>{qz=["minimax-m3","claude-opus-5","claude-fable-5-1","qwen3.8-max-0902"],zF={packy:qz,"packy-secondary":qz,"packy-codex":["kimi-k3","grok-4.6"]}});function VJ($){return $.replace(/\[1m\]$/,"")==="gemini-3.8-flash"}function WF($,Z,J){let Q=Z==="claude"?s4:Q9,Y=$.reasoning?.supported_efforts;if(Y!==void 0&&(!Array.isArray(Y)||!Y.length||!Y.every((z)=>typeof z==="string")))throw Error(`PackyAPI ${$.id} 的推理档位声明无效`);let V=Y===void 0?[...Q]:Q.filter((z)=>Y.includes(z));if(!V.length)throw Error(`PackyAPI ${$.id} 未声明当前 Agent 可用的推理档位`);let X=J.effort?.trim(),H=X||$.reasoning?.default_effort||(Y===void 0?Z==="claude"?"default":"medium":void 0);if(X&&!V.includes(X))throw Error(`PackyAPI effort 无效: ${X}`);return{model:$.id,display:$.display,efforts:V,defaultEffort:typeof H==="string"&&V.includes(H)?H:null}}var YJ="LODESTAR_PACKY_API_KEY",Dz,Fz;var Uz=R(()=>{B0();j1();dZ();Pz();o$();I();s$();Q0();Dz={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"};Fz=[{id:"packy",agent:"claude",display:"PackyAPI"},{id:"packy-secondary",agent:"claude",display:"PackyAPI · 令牌2"},{id:"packy-codex",agent:"codex",display:"PackyAPI"}];for(let $ of Fz){let{id:Z,agent:J,display:Q}=$,Y=J==="claude"?"anthropic":"openai-response",V=(X)=>X.protocols.includes(Y)||J==="claude"&&VJ(X.id);L0({kind:Z,configSectionId:Z,build(X){let H=X.api_key?.trim()||X.auth_token?.trim()||"",z=f$(X.base_url?.trim()||J2),G=X.management_url?.trim()?f$(X.management_url):_4(z),W=X.management_token?.trim()||"",K=X.management_user_id?.trim()||"",_=!!(W||K||X.management_url?.trim()||X.billing_source?.trim()),j=X.model?.trim(),L=X.models===void 0?void 0:s(X.models),q=new Set([...s(X.custom_models),...L??[]]),D=(O)=>Lz(O,Z),F=[],U=(O)=>{let A=F.find((T)=>T.id===O);if(A&&!V(A)&&!q.has(O))throw Error(`PackyAPI ${O} 未声明 ${Y};确认兼容后可显式补录`)},M={id:Z,kind:Z,agent:J,display:X.display?.trim()||Q,enabled:!!H&&X.enabled!==!1,models:[],defaultModel:j??"",modelSelection:{mode:"allowlist",modelIds:L??[],availableModels:[]},..._?{usageAccount:{id:K$("packy-account",G,K),label:"PackyAPI"}}:{},modelCatalogState:{status:H&&X.enabled!==!1?"idle":"disabled",updatedAt:Date.now()},...J==="claude"?{modelEnvironmentRevision(O){return VJ(O)?JSON.stringify(Dz):"native-retries"}}:{},...J==="codex"?{codexApiProvider:{id:"packy",name:"PackyAPI",baseUrl:`${z}/v1`,envKey:YJ}}:{},async refreshModels(){if(M.models=[],F=[],!M.enabled){M.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}M.modelCatalogState={status:"loading",updatedAt:null};try{F=await lZ(z,H);let O=F.filter((S)=>V(S)||q.has(S.id));if(!O.length&&!q.size)throw Error(`PackyAPI 此令牌没有声明支持 ${Y} 的模型,请检查分组和模型限制`);let A=O.map((S)=>({...WF(S,J,X),...!S.protocols.includes(Y)&&q.has(S.id)?{origin:"custom"}:{}}));for(let S of q){if(A.some((h)=>h.model.toLowerCase()===S.toLowerCase()))continue;A.push({model:S,display:S,origin:"custom",...i1(M,X)})}if(j&&!A.some((S)=>S.model===j)){if(F.find((h)=>h.id===j))throw Error(`PackyAPI ${j} 未声明 ${Y},确认兼容后请显式补录`);if(!q.has(j))throw Error(`PackyAPI 默认模型不在目录中且未补录: ${j}`)}let T=L??A.filter((S)=>S.origin==="custom"||D(S.model)).map((S)=>S.model);if(L===void 0&&j&&!T.some((S)=>S.toLowerCase()===j.toLowerCase()))T.unshift(j);let y=T.map((S)=>A.find((h)=>h.model===S)??{model:S,display:S,efforts:[],defaultEffort:null,unavailableReason:"账号目录未返回该模型"});M.modelSelection.availableModels=A,M.models=y,M.modelSelection.modelIds=y.map((S)=>S.model),M.defaultModel=j??y.find((S)=>!S.unavailableReason)?.model??[...q][0]??"",M.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(O){M.models=[],F=[];let A=p0(O,[H]);B(`${Z} refreshModels MISS: ${A}`),M.modelCatalogState={status:"failed",updatedAt:Date.now(),error:A}}},resolveSpawnModel(O){return U(O),O},spawnEnv(O,A){if(!H)throw Error("PackyAPI API key missing");let T=A||M.defaultModel;if(!T)throw Error("PackyAPI 尚未选择模型");U(T);let y=l0(O);if(delete y[YJ],J==="codex"){for(let h 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 y[h];return y[YJ]=H,y}if(y.ANTHROPIC_BASE_URL=z,y.ANTHROPIC_AUTH_TOKEN=H,y.ANTHROPIC_API_KEY="",y.CLAUDE_CODE_NO_MODEL_FALLBACK="1",VJ(T))Object.assign(y,Dz);y.ANTHROPIC_MODEL=T,y.ANTHROPIC_SMALL_FAST_MODEL=T,y.CLAUDE_CODE_SUBAGENT_MODEL=T;for(let h of["OPUS","SONNET","HAIKU","FABLE"])y[`ANTHROPIC_DEFAULT_${h}_MODEL`]=T;let S={opus:"OPUS",sonnet:"SONNET",haiku:"HAIKU",fable:"FABLE"};for(let h of s(X.slots)){let[l,E,m]=h.split("=");if(!l||!Object.hasOwn(S,l)||!E||m!==void 0)throw Error(`PackyAPI slots 无效: ${h}`);if(!D1(M).some((Y0)=>Y0.model===E))throw Error(`PackyAPI slot 模型不在当前来源: ${E}`);U(E),y[`ANTHROPIC_DEFAULT_${S[l]}_MODEL`]=E}return y},readUsage(){return _?uZ(G,W,K):oH(z,H)}};return M},setup:{commandSuffix:Z,hint:()=>`发送 \`${Z}-setup [base_url] <api_key>\` 配置${Q}。${Z==="packy-codex"?"与 PackyAPI 主账号共用凭据。":""}`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length<1||H.length>2||/^https?:\/\//i.test(H.at(-1)))return{error:`用法: ${Z}-setup [base_url] <api_key>`};try{return{config:{agent:J,api_key:H.at(-1),base_url:f$(H.length===2?H[0]:J2)}}}catch(z){return{error:p0(z,[H.at(-1)])}}},async validate(X){if(!(await lZ(X.base_url??J2,X.api_key??X.auth_token??"")).some(V)&&!s(X.custom_models).length&&!s(X.models).length)throw Error(`此令牌没有声明支持 ${Y} 的模型`)}},...Z==="packy-codex"?{}:{usageSetup:{commandSuffix:`${Z}-balance`,hint:()=>`发送 \`${Z}-balance-setup [management_url] <user_id> <system_token>\` 配置真实余额;共用已有账号用 \`${Z}-balance-setup share <source_id>\`。`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length===2&&H[0]==="share"){if(!Fz.some((W)=>W.id===H[1])||H[1]===Z)return{error:"请指定另一个已配置的 PackyAPI 来源:packy、packy-secondary 或 packy-codex"};return{config:{billing_source:H[1],management_token:"",management_user_id:"",management_url:""}}}if(H.length<2||H.length>3)return{error:`用法:${Z}-balance-setup [management_url] <user_id> <system_token>,或 ${Z}-balance-setup share <source_id>`};let z=H.at(-2),G=H.at(-1);if(!/^[1-9]\d*$/.test(z)||!Number.isSafeInteger(Number(z)))return{error:"用户 ID 必须是正整数"};try{return{config:{billing_source:"",management_token:G,management_user_id:z,management_url:H.length===3?f$(H[0]):""}}}catch(W){return{error:p0(W,[G])}}},async validate(X){let H=X.management_url||_4(X.base_url||J2),z=await uZ(H,X.management_token||"",X.management_user_id||"",!0);if(z.state!=="ok")throw Error(z.reason||"PackyAPI 真实账户余额查询失败")}}}})}});var Mz=1;import{EventEmitter as KF}from"node:events";import{createRequire as BF}from"node:module";import{createHash as _F,randomUUID as jF}from"node:crypto";import{createInterface as qF}from"node:readline";import{dirname as LF,join as $1,isAbsolute as PF}from"node:path";import{fileURLToPath as XJ}from"node:url";import{tmpdir as DF}from"node:os";import{existsSync as Oz,mkdirSync as Az,mkdtempSync as FF,readFileSync as C9,renameSync as UF,writeFileSync as Nz,rmSync as HJ}from"node:fs";import MF from"cross-spawn";function OF($){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 AF($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=C9($1($,".mcp.json"),"utf8")}catch(Y){if(Y?.code==="ENOENT")return[];throw Y}let Q=JSON.parse(J);if(!Q.mcpServers||typeof Q.mcpServers!=="object"||Array.isArray(Q.mcpServers))throw Error("DSH project .mcp.json must contain an mcpServers object");return Object.entries(Q.mcpServers).map(([Y,V])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Y)||!V||typeof V!=="object")throw Error(`invalid DSH MCP server: ${Y}`);let X=V,H=X.type==="http"?{transport:"streamable-http",serverName:Y,url:X.url,headers:X.headers??{}}:X.type===void 0||X.type==="stdio"?{transport:"stdio",serverName:Y,command:X.command,args:X.args??[],env:X.env??{},cwd:$}:null;if(!H)throw Error(`DSH does not support MCP transport ${X.type} for ${Y}`);return{id:`lodestar-mcp-${Y}`,name:"@deepseek-ai/dsh-mcp-client",config:{...H,failOnStartupError:!0}}})}async function P4($,Z,J={}){let Q=new $6($);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 $6;var b9=R(()=>{V0();h2();I();$6=class $6 extends KF{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!PF($.cwd))throw Error("DSH requires an absolute workspace");let Z=p3("dsh"),Q=BF($1(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Y=JSON.parse(C9(Q,"utf8"));B(`dsh runtime: ${Y.version} (${Z})`);let V=OF($.env),X=$.home??E2;Az(X,{recursive:!0,mode:448});let H=AF($.cwd,$.profile);this.launchDir=FF($1(DF(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),G=z?"dsh-bridge.ts":"dsh-bridge.js",W=C9(XJ(new URL(`./${G}`,import.meta.url))),K=z?C9(XJ(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(C9(XJ(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),L=_F("sha256").update(W).update(K).update(j).digest("hex").slice(0,20),q=$1(Z,".lodestar-bridges",L);Az(q,{recursive:!0});let D=$1(q,G),F=(S,h)=>{if(Oz(S))return;let l=`${S}.${jF()}.tmp`;try{Nz(l,h),UF(l,S)}finally{if(Oz(l))HJ(l)}};if(F($1(q,"package.json"),j),z)F($1(q,"dsh-protocol.ts"),K);F(D,W);let U=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((S)=>({id:S,disabled:!0})),{id:"approval",config:{policy:"ask"}},{id:"permission",config:{defaultPreset:"lodestar",presets:{lodestar:{sandbox:"danger-full-access",approval:"ask"}}}},{id:"system-prompt",config:{personaPrefix:"You are a coding agent powered by {{model}}.",personaSuffix:"Your working directory is {{cwd}}."}},{id:"skill-filesystem",config:{includeDefaultRoots:!0,...$.managedSkillDir?{customSkillDirs:[$.managedSkillDir]}:{}}},{insert:[{id:"lodestar-bridge",name:D},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...H]},...V],M=$1(this.launchDir,"bridge.patch.yml");Nz(M,JSON.stringify(U),{mode:384});let O=$.env.LODESTAR_DSH_NODE||"node",A=[$1(LF(Q),Y.bin.dsh),"--profile","sdk","--patch",M,...($.patches??[]).flatMap((S)=>["--patch",S])],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 S of Object.keys(T))if(S.startsWith("LODESTAR_AGENT_"))delete T[S];try{this.child=MF(O,A,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...T,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(S){throw HJ(this.launchDir,{recursive:!0,force:!0}),S}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(S)=>{this.stderr=(this.stderr+S).slice(-16384),B(`dsh stderr: ${S.trimEnd()}`)}),this.child.stdin.on("error",(S)=>this.transportFailure(S));let y=qF({input:this.child.stdout,crlfDelay:1/0});y.on("line",(S)=>this.receive(S)),this.exitTask=new Promise((S)=>{this.child.once("error",(h)=>this.transportFailure(h)),this.child.once("close",(h,l)=>{this.exited=!0,y.close();let E=Error(`DSH exited code=${h} signal=${l}
115
- ${this.stderr}`);this.rejectPending(E),HJ(this.launchDir,{recursive:!0,force:!0}),S(),this.emit("exit",{code:h,signal:l,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==Mz||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
114
+ ${Z.stderr}`)}function mZ($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var bH,kH,PZ,Z$,O1=async($)=>{try{let Z=await y8.defaultHttpInstance.request({...$,$return_headers:!0}),J=F$({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=F$(Z);Z.message=k(Z),Object.assign(Z,{apiMessage:J.message,logId:J.logId})}throw Z}},FD,W0,wH=15000,C8="",AH=0,BZ=null,j0,_0,U0,Z0,TH=200,xH,I0,m8=31457280,ED;var e=R(()=>{o0();b2();t5();B0();f0();j1();B0();V0();I();D0();v0();E8();h0();u1();UH();bH=p.feishu.app_id,kH=p.feishu.app_secret,PZ=p.runtime.projects_root,Z$=new Map;FD={request:O1,get:($,Z)=>O1({...Z,url:$,method:"GET"}),delete:($,Z)=>O1({...Z,url:$,method:"DELETE"}),head:($,Z)=>O1({...Z,url:$,method:"HEAD"}),options:($,Z)=>O1({...Z,url:$,method:"OPTIONS"}),post:($,Z,J)=>O1({...J,url:$,data:Z,method:"POST"}),put:($,Z,J)=>O1({...J,url:$,data:Z,method:"PUT"}),patch:($,Z,J)=>O1({...J,url:$,data:Z,method:"PATCH"})},W0=new y8.Client({appId:bH,appSecret:kH,disableTokenCache:!1,httpInstance:FD});j0=new Map,_0=new Map;U0=new Map;Z0=new Map;xH=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;I0=new Map;ED=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});async function lH($=(Z)=>new t$({accountId:Z})){if(g2(c))throw Error("默认账号正在登录,请先完成默认账号授权,再添加额外账号。");let Z,J,Q;try{Z=$(c),await Z.initialize("lodestar-login-check"),Q=await P1(()=>Z.request("account/read",{refreshToken:!1}),"默认账号登录检查")}catch(Y){J=Error(`默认账号登录检查失败:${B4(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,`默认账号检查进程关闭失败:${B4(Y).message}`].filter(Boolean).join(";"),{cause:Y})}if(J)throw J}class uH{createClient;waitMs;recordLogin;stateWaitMs;attempts=new Map;stopping=!1;constructor($=(Y)=>new t$({accountId:Y,login:!0}),Z=900000,J=(Y,V)=>{v.recordLogin(Y,V),L1(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=lV($),Q;try{Q=this.createClient($)}catch(z){throw J(),z}let Y,V,X=new Promise((z,G)=>{Y=z,V=G});X.catch(()=>{});let H={owner:Z,client:Q,accountId:$,loginId:null,loginRequested:!1,loginSucceeded:!1,authUpdated:!1,finishing:!1,done:X,resolve:Y,reject:V,timer:null,notification:()=>{},closed:()=>{},early:[],releaseAuth:J};H.notification=(z,G)=>{if(H.finishing||!H.loginRequested)return;if(z==="account/updated"){if(G?.authMode==="chatgpt"){if(H.authUpdated=!0,H.loginSucceeded)this.finish(H)}return}if(z!=="account/login/completed")return;if(!H.loginId){H.early.push(G);return}if(G?.loginId!==H.loginId)return;if(G?.success!==!0){this.finish(H,Error(typeof G?.error==="string"?G.error:"Codex 登录未成功"));return}if(H.loginSucceeded)return;if(H.loginSucceeded=!0,B(`codex-login: authorization completed account=${$} authUpdated=${H.authUpdated}`),H.timer)clearTimeout(H.timer);if(H.authUpdated)this.finish(H);else H.timer=setTimeout(()=>{this.finish(H,Error("设备码授权已完成,但 Codex 未及时更新账号状态;认证文件已保留,可用 codex-accounts 检查"))},this.stateWaitMs)},H.closed=(z)=>{this.finish(H,z)},Q.on("notification",H.notification),Q.on("closed",H.closed),Q.on("protocolError",H.closed),this.attempts.set($,H);try{await Q.initialize("lodestar-login"),H.loginRequested=!0;let z=await Q.request("account/login/start",{type:"chatgptDeviceCode"},30000);if(z?.type!=="chatgptDeviceCode"||typeof z.loginId!=="string"||!z.loginId||typeof z.userCode!=="string"||!z.userCode||typeof z.verificationUrl!=="string"||new URL(z.verificationUrl).protocol!=="https:")throw Error("Codex 设备码登录响应不完整");if(H.loginId=z.loginId,H.finishing)throw await X,Error("登录已结束");H.timer=setTimeout(()=>{this.cancelAttempt(H,"登录等待超过 15 分钟,请重新发送 codex-login [备注]").catch(()=>{})},this.waitMs);for(let G of H.early)H.notification("account/login/completed",G);return H.early.length=0,{accountId:$,loginId:z.loginId,verificationUrl:z.verificationUrl,userCode:z.userCode,done:X}}catch(z){return await this.finish(H,B4(z)),await X}}pending($){return[...this.attempts.values()].filter((Z)=>Z.owner.chatId===$.chatId&&Z.owner.userOpenId===$.userOpenId).map((Z)=>Z.accountId)}async cancel($,Z){let J=this.attempts.get($);if(!J)throw Error("该账号没有等待中的登录");if(!Z.userOpenId||Z.chatId!==J.owner.chatId||Z.userOpenId!==J.owner.userOpenId)throw Error("只有发起登录的用户可在原群取消");if(J.finishing)throw Error("登录正在收尾,请等待结果");await this.cancelAttempt(J,"登录已取消")}async cancelAttempt($,Z){if($.finishing)return;$.finishing=!0;let J=Error(Z);if($.loginId&&$.client.isAlive())try{await $.client.request("account/login/cancel",{loginId:$.loginId})}catch(Q){J=Error(`${Z};取消请求失败:${B4(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=B4(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,`登录进程关闭失败:${B4(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 B4($){return $ instanceof Error?$:Error(String($))}var $2;var pZ=R(()=>{M$();D0();I();$2=new uH});import{readFileSync as CD}from"node:fs";import{homedir as bD}from"node:os";import{join as aH}from"node:path";function wD(){return process.env.CLAUDE_CONFIG_DIR||aH(bD(),".claude")}function cZ(){try{let $=CD(aH(wD(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return B(`glm-usage: read settings.json env failed: ${$}`),{}}}function Z2($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function yD($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function vD($){let Z=yD($);return Z&&Z2($)?Z:null}function iH($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function nH($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function fD($){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:iH(W.percentage),resetsAt:nH(W.nextResetTime)}:null,H=X(Q),z=X(Y),G=V?{percent:iH(V.percentage),resetsAt:nH(V.nextResetTime),...typeof V.currentValue==="number"?{used:V.currentValue}:{},...typeof V.usage==="number"?{total:V.usage}:{}}:null;if(!H&&!z&&!G)return{state:"network",reason:"GLM 额度响应没有可识别的额度窗口"};return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:H,weekly:z,monthly:G,fetchedAt:Date.now()}}async function c8($,Z){let J=$!==void 0||Z!==void 0?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:cZ(),Q=J.ANTHROPIC_AUTH_TOKEN,Y=J.ANTHROPIC_BASE_URL||"";if(!Q)return{state:"no_credentials"};let V=vD(Y);if(!V)return{state:"not_glm",baseUrl:Y||void 0};return kD.readStale(K$("glm",V,Q),()=>hD(V,Q))}async function hD($,Z){let J=`${$}/api/monitor/usage/quota/limit`,Q=new AbortController,Y=setTimeout(()=>Q.abort(),dH);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:b$(V.headers)};let X=await V.json(),H=X?.error?.code??X?.code;if(X?.success===!1||X?.error!=null||H!==void 0&&String(H)!=="200"){let W=X?.error?.message??X?.msg??X?.message??(typeof X?.error==="string"?X.error:void 0),K=[H===void 0?"":`code ${H}`,W===void 0?"":String(W)].filter(Boolean).join(": ").replaceAll(Z,"[redacted]")||"GLM 额度接口返回失败";return B(`glm-usage: quota/limit MISS: ${K}`),{state:String(H)==="429"?"rate_limited":"network",reason:K,retryAfterMs:b$(V.headers)}}let z=X?.data??X,G=fD(z);if(G.state==="network")B(`glm-usage: quota/limit MISS: ${G.reason}`);return G}catch(V){let X=(V?.name==="AbortError"?`timeout ${dH}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 dH=1e4,kD;var l8=R(()=>{o0();I();s$();kD=new $$});function f$($){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 _4($){let Z=f$($),J=new URL(Z);return J.protocol==="https:"&&!J.port&&J.pathname==="/"&&["cf.api.fan","slb-v1.api.fan","www.packyapi.ai"].includes(J.hostname)?ID:Z}function lZ($,Z){let J=f$($),Q=K$("packy-models",J,Z),Y=u8.get(Q);if(Y)return Y;let V=S$(`${J}/v1/models`,Z,"PackyAPI models").then((X)=>{let H=new Set;return X.map((z)=>{if(typeof z.id!=="string"||!z.id.trim()||H.has(z.id)||!Array.isArray(z.supported_endpoint_types)||!z.supported_endpoint_types.length||!z.supported_endpoint_types.every((G)=>typeof G==="string"&&G))throw Error("PackyAPI 模型目录缺少有效 id/协议声明,或含重复模型");return H.add(z.id),{id:z.id,display:typeof z.name==="string"&&z.name?z.name:z.id,protocols:[...z.supported_endpoint_types],...v$(z.reasoning)?{reasoning:z.reasoning}:{}}})}).finally(()=>{if(u8.get(Q)===V)u8.delete(Q)});return u8.set(Q,V),V}function v$($){return $!==null&&typeof $==="object"&&!Array.isArray($)}async function i8($,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 e$(Q.status,"响应不是有效 JSON",b$(Q.headers))}let X=v$(V)?V.code:void 0,H=X!==void 0&&![!0,0,200,"0","200"].some((z)=>z===X);if(!Q.ok||!v$(V)||V.success===!1||H||V.error!=null){let z=v$(V)&&v$(V.error)?V.error.message:v$(V)?V.message:null;throw new e$(Q.status,typeof z==="string"?z:"上游接口返回错误",b$(Q.headers))}return V}async function uZ($,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=f$($),V=K$("packy-balance",Y,JSON.stringify([J,Z])),X=async()=>{try{let z=await i8(`${Y}/api/user/self`,Z,{"New-Api-User":J}),G=z.data;if(z.success!==!0||!v$(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 i8(`${Y}/api/status`)).data;if(!v$(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(z){let G=p0(z,[Z]);return B(`PackyAPI balance MISS: ${G}`),{state:z instanceof e$&&[401,403].includes(z.status)?"no_credentials":z instanceof e$&&z.status===429?"rate_limited":"network",kind:"balance",windows:[],reason:G,...z instanceof e$&&z.retryAfterMs!==void 0?{retryAfterMs:z.retryAfterMs}:{}}}};if(!Q)return d8.readStale(V,X);let H=await X();if(H.state==="ok")d8.prime(V,H);else d8.invalidate(V);return H}async function oH($,Z){if(!Z)return{state:"no_credentials",kind:"quota",windows:[]};let J=_4($);return d8.readStale(K$("packy",J,Z),async()=>{try{let Y=(await i8(`${J}/api/usage/token/`,Z)).data;if(!v$(Y)||typeof Y.unlimited_quota!=="boolean")throw Error("PackyAPI 令牌配额响应缺少 unlimited_quota");if(Y.unlimited_quota)return{state:"not_applicable",kind:"balance",windows:[],reason:"此 API key 为无限额度令牌;令牌接口不提供账户余额,需要系统访问令牌查询。"};let{total_available:V,total_granted:X}=Y;if(typeof V!=="number"||!Number.isFinite(V)||typeof X!=="number"||!Number.isFinite(X)||X<0)throw Error("PackyAPI 令牌配额数值缺失或无效");let H=(await i8(`${J}/api/status`)).data;if(!v$(H)||typeof H.quota_per_unit!=="number"||!Number.isFinite(H.quota_per_unit)||H.quota_per_unit<=0||H.quota_display_type!=="USD")throw Error("PackyAPI 配额单位缺失或不是已支持的 USD 额度单位");return{state:"ok",kind:"quota",windows:[],fetchedAt:Date.now(),quota:{remaining:V/H.quota_per_unit,limit:X/H.quota_per_unit,currency:"USD"}}}catch(Q){let Y=p0(Q,[Z]);return B(`PackyAPI quota MISS: ${Y}`),{state:Q instanceof e$&&[401,403].includes(Q.status)?"no_credentials":Q instanceof e$&&Q.status===429?"rate_limited":"network",kind:"quota",windows:[],reason:Y,...Q instanceof e$&&Q.retryAfterMs!==void 0?{retryAfterMs:Q.retryAfterMs}:{}}}})}var J2="https://cf.api.fan",ID="https://www.packyapi.ai",u8,e$,d8;var dZ=R(()=>{o0();k2();s$();I();u8=new Map;e$=class e$ extends Error{status;retryAfterMs;constructor($,Z,J){super(`PackyAPI HTTP ${$}: ${Z}`);this.status=$;this.retryAfterMs=J}};d8=new $$});function sH($){return o8.find((Z)=>Z.other===$)?.id??$}function tH($){let Z=o8.find((J)=>J.id===$||J.other===$);return Z?[Z.id,Z.other]:[$]}function x9($){let Z=$.api_key?.trim(),J=$.auth_token?.trim();if(Z&&J&&Z!==J)throw Error("同一账号的 api_key 与 auth_token 不一致,请重新配置");return Z||J}function a8($,Z){if($.id==="packy")return f$(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 u4(`${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 n8($,Z){let J=a8($,Z);return $.id==="deepseek"?J.replace(/\/anthropic$/,""):J}function j4($){let{api_key:Z,auth_token:J,base_url:Q,...Y}=$;return Y}function iZ($,Z,J={}){let Q=Z[$.id]??{},Y=Z[$.other]??{},V=x9(Q),X=x9(Y),H=Q.base_url?.trim(),z=Y.base_url?.trim();if(V&&X&&V!==X||H&&z&&n8($,H)!==n8($,z))throw Error(`${$.id} 与 ${$.other} 的旧账号配置冲突;请用 ${$.id}-setup 重新设置共享账号`);if(V||X)return{key:V||X,base:a8($,H||z||$.base)};let G=J[$.id]??J[$.other]??{};if(x9(G)&&(H||z)&&G.base_url&&n8($,H||z)!==n8($,G.base_url))throw Error(`${$.id} 的平台地址与本机识别的账号不一致,请用 ${$.id}-setup 配置 Key`);return{key:x9(G),base:a8($,H||z||G.base_url||$.base)}}function E9($,Z={}){let J={...$};for(let Q of o8){let{key:Y,base:V}=iZ(Q,$,Z);J[Q.id]={...j4($[Q.id]??{}),base_url:V,...Q.id==="glm"?{auth_token:Y??""}:{api_key:Y??""}},J[Q.other]={...j4($[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 gD(J),J}function gD($){let Z=new Set(["packy","packy-secondary","packy-codex"]),J=new Set,Q=new Set,Y=(X)=>!!(X.management_token?.trim()||X.management_user_id?.trim()||X.management_url?.trim()),V=(X)=>{if(Q.has(X))throw Error(`PackyAPI 余额账号引用循环:${X}`);if(J.has(X))return $[X];Q.add(X);let H=$[X]??{},z=H.billing_source?.trim(),G=z||(X==="packy-codex"&&!Y(H)?"packy":void 0);if(G){if(!Z.has(G)||!$[G])throw Error(`PackyAPI 余额账号引用不存在:${G}`);if(z&&Y(H))throw Error(`PackyAPI ${X} 不能同时配置 billing_source 和独立余额凭据`);let W=V(G);$[X]={...H,...z||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||_4(W.base_url||J2)}:{}}}return Q.delete(X),J.add(X),$[X]??H};for(let X of Z)if($[X])V(X)}function nZ($,Z,J){let Q=Object.fromEntries(Object.entries(J).filter(([,z])=>z!==void 0)),Y={...$,[Z]:{...$[Z],...Q}},V=o8.find((z)=>z.id===Z||z.other===Z);if(!V)return{[Z]:Y[Z]};let X=J.api_key!==void 0||J.auth_token!==void 0,H=J.base_url!==void 0;if(X||H){let z=$[Z]??{},G=$[V.id]??{},W=$[V.other]??{},K=X?x9(J):iZ(V,$).key,_=a8(V,J.base_url?.trim()||z.base_url||G.base_url||W.base_url||V.base);Y[V.id]={...j4(Y[V.id]??{}),base_url:_,...V.id==="glm"?{auth_token:K??""}:{api_key:K??""}},Y[V.other]=j4(Y[V.other]??{})}else{let{key:z,base:G}=iZ(V,Y);Y[V.id]={...j4(Y[V.id]??{}),base_url:G,...V.id==="glm"?{auth_token:z??""}:{api_key:z??""}},Y[V.other]=j4(Y[V.other]??{})}return{[V.id]:Y[V.id],[V.other]:Y[V.other]}}var o8;var S9=R(()=>{d4();dZ();o8=[{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 pD($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function s8($,Z,J){try{let Q=await X0(pD($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(mD)});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 mD=15000;var aZ=R(()=>{o0();I()});function rH($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function cD($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function eH($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function lD($){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 uD($){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 oZ($){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(rH($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(rH($.weekly,"weekly","周额度"));if($.monthly)Z.push(cD($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var sZ=R(()=>{Q0();l8();Z4();B9();aZ();I();d4();L0({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)&&Z2(J),V=$.model?.trim()||void 0,X=uD($.slots),H={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await tX(J,Q),W=[...new Set([...eH($.models),...eH($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:$4,defaultEffort:"max",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=lD(H.models.map((K)=>K.model));for(let K of H.models){let _=t2("glm",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`glm refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...l0(z)};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(z){return j8("glm",z)},async verifyModel(z){return s8(J,{Authorization:`Bearer ${Q}`},z)},async readUsage(){return oZ(await c8(J,Q))}};return H},setup:{commandSuffix:"glm",hint:($)=>`配置 ${$}:发送 \`glm-setup <api_key>\`(智谱国内站),或 \`glm-setup <base_url> <api_key>\`(指定平台)。Claude Code 和 DeepSeek Harness 共用该账号;校验失败保留原配置。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:glm-setup <api_key>,或 glm-setup <base_url> <api_key>;只填写 Key 本身,不加 Bearer 前缀。"};try{return{config:{agent:"claude",base_url:u4(Z.length===2?Z[0]:w2),auth_token:Z.at(-1)}}}catch(J){return{error:J instanceof Error?J.message:String(J)}}},async validate($){await y2($.base_url??w2,$.auth_token??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!Z2(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var $z=R(()=>{Q0();Z4();L0({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 dD}from"node:os";function r8($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function t8($,Z,J){if($==null)return{kind:Z,label:J,percent:null,resetsAt:null};if(!r8($))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 Jz($){return $.trim().toLowerCase().replace(/^claude:/,"").replace(/\[1m\]$/,"").replace(/^claude[-\s]+/,"").replace(/^(?:\d+[.-])+/,"").split(/[-\s]+/,1)[0]}function Qz($,Z){if($.state!=="ok"||!Z?.trim())return null;let J=Jz(G9(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&&Jz(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 nD($){if(!r8($)||typeof $.subscription_type!=="string"||!$.subscription_type.trim())throw Error("Claude 订阅额度响应缺少订阅身份");if($.rate_limits_available!==!0)throw Error("Claude 原生接口未开放当前订阅额度查询");if(!r8($.rate_limits))throw Error("Claude 原生额度接口未返回 rate_limits 数据");let Z=$.rate_limits,J=[t8(Z.five_hour,"fiveHour","5h 窗口"),t8(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(t8(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(!r8(Y)||typeof Y.display_name!=="string"||!Y.display_name.trim())throw Error("Claude 模型专属额度缺少模型名称");let V=Y.display_name.trim();J.push(t8(Y,`modelWeekly:${V}`,`${V} 周额度`)),Q=!0}}if(!Q)throw Error("Claude 原生额度接口未返回任何订阅额度窗口");return{state:"ok",windows:J,fetchedAt:Date.now()}}async function Yz($){return iD.readStale("claude-subscription",()=>aD($))}async function aD($){try{let{ClaudeAgentProcess:Z}=await Promise.resolve().then(() => (e2(),i5)),J=new Z({workDir:dD(),effort:"default",allowDelegation:!1,profile:{loadProjectMcp:!1},...$});J.on("error",(V)=>B(`Claude subscription usage MISS: ${V.message}`));let Q,Y;try{let V=await Promise.race([J.readSubscriptionUsage(),new Promise((X,H)=>{Q=setTimeout(()=>H(Error(`Claude 订阅额度查询超时(${Zz/1000}s)`)),Zz)})]);return nD(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":n2(Z)?"rate_limited":"network",windows:[],reason:J}}}var Zz=30000,iD;var tZ=R(()=>{I();I5();s$();iD=new $$});function oD(){let $=Object.fromEntries(_8.map((Z)=>[Z,""]));return $.ANTHROPIC_BASE_URL="https://api.anthropic.com",$.CLAUDE_CODE_NO_MODEL_FALLBACK="1",{env:$,apiKeyHelper:"",forceLoginMethod:"claudeai"}}function sD($){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 Vz=R(()=>{B0();I();Q0();Z4();tZ();o$();L0({kind:"claude-subscription",configSectionId:"claude-sub",build($){let Z=oD(),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:sD,spawnEnv(X){return{...l0(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 H=[...s($.custom_models),...s($.models)];if(J&&!X.some((z)=>z.model===J)&&!H.includes(J))throw Error(`Claude Code 订阅默认模型不在目录中且未补录: ${J}`);if($.effort){let z=X.find((G)=>G.model===(J??X[0].model));if(!A0($.effort)||z&&!z.efforts.includes($.effort))throw Error(`Claude Code 订阅默认模型不支持 effort: ${$.effort}`);if(z)z.defaultEffort=$.effort}V.defaultModel=J??X[0].model,V.models=X,V.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(X){let H=X instanceof Error?X.message:String(X);if(B(`claude-sub refreshModels MISS: ${H}`),X?.code==="CLAUDE_SUBSCRIPTION_AUTH_MISSING")V.enabled=!1;V.modelCatalogState={status:V.enabled?"failed":"disabled",updatedAt:Date.now(),error:H}}},readUsage(){if(!V.enabled)return Promise.resolve({state:"not_applicable",windows:[],reason:V.modelCatalogState?.error??"Claude Code 订阅已在 Lodestar 中禁用;发送 claude-sub on 启用"});return Y??=Yz({settingSources:["user"],settings:Z,transformEnv:V.spawnEnv,validateAccount:V.validateClaudeAccount,tokenSourceId:V.id}).finally(()=>{Y=void 0}),Y}};return V}})});function Hz($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function tD($){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 rD($){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 eD($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function zz($,Z){return(await rZ(new URL($).origin,Z)).map((Q)=>({model:Q,display:Q,efforts:$4,defaultEffort:"high"}))}async function rZ($,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 S$(`${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 eZ($,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 ZF.readStale(K$("deepseek",J,Z),()=>JF(J,Z))}async function JF($,Z){try{let J=await X0(`${$}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout($F)});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:b$(J.headers)};let Q=await J.json(),V=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof V?.currency==="string"?V.currency:"",H=V?.total_balance;if(!X||typeof H!=="string"&&typeof H!=="number"||String(H).trim()===""||!Number.isFinite(Number(H)))throw Error("余额明细缺失或无效");return{kind:"balance",state:"ok",fetchedAt:Date.now(),windows:[],balance:{remaining:Number(H),currency:X}}}catch(J){return B(`deepseek readUsage MISS: ${J?.message??J}`),{kind:"balance",state:"network",windows:[],reason:J?.message??String(J)}}}var Xz="https://api.deepseek.com/anthropic",$F=1e4,ZF;var $J=R(()=>{o0();Q0();Z4();B9();aZ();I();k2();s$();ZF=new $$;L0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||Xz,Q=$.api_key?.trim()||Z?.api_key?.trim()||"",Y=!!Q,V=$.model?.trim()||void 0,X=rD($.slots),H={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Y,models:[],modelCatalogState:{status:Y?"idle":"disabled",updatedAt:Date.now()},defaultModel:V??"",async refreshModels(){if(!H.enabled){H.models=[],H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await zz(J,Q),W=[...new Set([...Hz($.models),...Hz($.custom_models)])].filter((K)=>!z.some((_)=>_.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:$4,defaultEffort:"high",origin:"custom"}));if(H.models=[...z,...W],!V)H.defaultModel=tD(H.models.map((K)=>K.model));for(let K of H.models){let _=t2("deepseek",K.model);K.context1m=_!=null&&_>=1e6||void 0}H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){B(`deepseek refreshModels MISS: ${z?.message??z}`),H.models=[],H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:z?.message??String(z)}}},spawnEnv(z){let W={...l0(z)};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(z){return j8("deepseek",z)},async verifyModel(z){return s8(J,{"x-api-key":Q},z)},async readUsage(){if(!Q)return{kind:"balance",state:"no_credentials",windows:[]};return eZ(J,Q)}};return H},setup:{commandSuffix:"deepseek",hint:($)=>`配置 ${$}:发送 \`deepseek-setup <api_key>\`;Claude Code 和 DeepSeek Harness 共用该账号。自建端点用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length||Z.length>2||/^https?:\/\//i.test(Z.at(-1)))return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Q=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Q}}},async validate($){await zz($.base_url??Xz,$.api_key??"")}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!eD(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});function Q2($){let Z=$.toLowerCase().replace(/^~/,"");return/^(openai|deepseek|z-ai|zai-org|thudm)\//.test(Z)||/^(openrouter\/|@)/.test(Z)}var ZJ;var Gz=R(()=>{ZJ=[{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 Y2($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function QJ($){return $ instanceof Error?$.message:String($)}function Kz($){return[...new Set(($??"").split(",").map((Z)=>Z.trim()).filter(Boolean))]}function q4($){return $.replace(/\[1m\]$/,"")}function L4($){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 VF($,Z,J){if(!Z)throw Error("OpenRouter API key missing");let Q=await X0(`${L4($)}/v1/${J}`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(QF)});if(!Q.ok){let Y=await Q.text(),V="";if(Y.trim().startsWith("{"))try{let X=JSON.parse(Y);if(Y2(X)&&Y2(X.error)&&typeof X.error.message==="string")V=X.error.message}catch{}throw new e8(Q.status,V.replaceAll(Z,"[redacted]"),b$(Q.headers))}return Q.json()}async function Bz($,Z){let J=await S$(`${L4($)}/v1/models/user`,Z,"OpenRouter models"),Q=[],Y=new Set;for(let V of J){if(!Y2(V)||typeof V.id!=="string"||!V.id||typeof V.name!=="string")throw Error("OpenRouter models: 模型 id/name 无效");if(!Y2(V.architecture)||!Array.isArray(V.architecture.output_modalities)||!Array.isArray(V.supported_parameters))throw Error(`OpenRouter models: ${V.id} 的模型能力缺失`);if(Q2(V.id)||!V.architecture.output_modalities.includes("text")||!V.supported_parameters.includes("tools")||V.id.endsWith(":batch")||Y.has(V.id))continue;let X=Y2(V.reasoning)?V.reasoning:void 0,H=X?.supported_efforts,z=H===null||H===void 0&&V.supported_parameters.includes("reasoning_effort")?["max","xhigh","high","medium","low"]:Array.isArray(H)?[...new Set(H.filter((_)=>_!=="default"&&A0(_)))]:["default"],G=ZJ.find((_)=>_.model===V.id),W=G?z.includes(G.effort)?G.effort:null:z[0]==="default"?"default":A0(X?.default_effort)&&z.includes(X.default_effort)?X.default_effort:null,K=t2("openrouter",V.id);Q.push({model:V.id,display:V.name,efforts:z,defaultEffort:W,context1m:K!==void 0&&K>=1e6||void 0}),Y.add(V.id)}if(!Q.length)throw Error("OpenRouter 未返回支持文本和工具调用的交互模型");return Q}function _z($){return typeof $==="number"&&Number.isFinite($)&&$>=0}async function XF($,Z){if(!Z)return{kind:"balance",state:"no_credentials",windows:[]};return YF.readStale(K$("openrouter",L4($),Z),()=>HF($,Z))}async function HF($,Z){try{let J=await VF($,Z,"credits");if(!Y2(J)||!Y2(J.data))throw Error("OpenRouter credits: data 对象缺失");let{total_credits:Q,total_usage:Y}=J.data;if(!_z(Q)||!_z(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=QJ(J);return B(`openrouter readUsage MISS: ${Q}`),{kind:"balance",state:J instanceof e8&&J.status===429?"rate_limited":"network",windows:[],reason:Q,...J instanceof e8?{retryAfterMs:J.retryAfterMs}:{}}}}var Wz="https://openrouter.ai/api",QF=1e4,YF,JJ,e8;var jz=R(()=>{o0();B0();Q0();B9();I();Gz();k2();s$();YF=new $$,JJ={opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"};e8=class e8 extends Error{status;retryAfterMs;constructor($,Z,J){super(`HTTP ${$}${Z?`: ${Z}`:""}`);this.status=$;this.retryAfterMs=J}};L0({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()||Wz,V=$.model?.trim()||"",X=$.models===void 0?ZJ.map((z)=>z.model):Kz($.models),H={id:"openrouter",kind:"openrouter",agent:"claude",display:$.display?.trim()||"OpenRouter",enabled:!!Q,models:[],defaultModel:V,modelSelection:{mode:"allowlist",modelIds:X,availableModels:[]},validateCustomModelId(z){if(Q2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);if(!z.includes("/"))throw Error("OpenRouter 模型请填写完整的 作者/模型 ID")},modelEnvironmentRevision(z){let G=H.modelSelection.availableModels.find((W)=>q4(W.model)===q4(z));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(H.models=[],H.modelSelection.availableModels=[],!H.enabled){H.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}H.modelCatalogState={status:"loading",updatedAt:null};try{let z=await Bz(Y,Q),G=z.find((K)=>K.model===q4(V));if(V&&!G)throw Error(`OpenRouter 默认模型不在账号目录中: ${V}`);if($.effort){if(!V)throw Error("OpenRouter effort 需要同时配置 model");if(!A0($.effort)||!G.efforts.includes($.effort))throw Error(`OpenRouter 模型 ${V} 不支持 effort ${$.effort}`);G.defaultEffort=$.effort}let W=X.map((K)=>{let _=z.find((j)=>j.model===q4(K));if(!_)return{model:K,display:K,efforts:[],defaultEffort:null,unavailableReason:Q2(K)?"此厂商或自动路由已被排除":"账号目录未返回该模型"};return{..._,model:K}});H.models=W,H.modelSelection.availableModels=z,H.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(z){let G=QJ(z);B(`openrouter refreshModels MISS: ${G}`),H.modelCatalogState={status:"failed",updatedAt:Date.now(),error:G}}},spawnEnv(z,G){if(!Q)throw Error("OpenRouter API key missing");let W=G||V;if(!W)throw Error("OpenRouter 未选择模型,请通过 model 面板选择或配置 model");if(Q2(W))throw Error(`OpenRouter 已排除此厂商或自动路由: ${W}`);let K=l0(z);K.ANTHROPIC_BASE_URL=L4(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 _ of Object.values(JJ))K[_]=W;for(let _ of Kz($.slots)){let j=_.indexOf("="),L=_.slice(0,j).trim(),q=_.slice(j+1).trim();if(j<1||!Object.hasOwn(JJ,L)||!q)throw Error(`OpenRouter slots 无效: ${_}`);if(Q2(q)||!H.modelSelection.availableModels.some((D)=>!D.unavailableReason&&q4(D.model)===q4(q)))throw Error(`OpenRouter slot 模型不在账号目录中: ${q}`);if(H.modelEnvironmentRevision(q)!==H.modelEnvironmentRevision(W))throw Error(`OpenRouter slot 不能混合无 effort 档位与有 effort 档位的模型: ${q}`);K[JJ[L]]=q}return K},resolveSpawnModel(z){if(Q2(z))throw Error(`OpenRouter 已排除此厂商或自动路由: ${z}`);return z||void 0},readUsage(){return XF(Y,Q)}};return H},setup:{commandSuffix:"openrouter",hint:($)=>`启用 ${$}:发送 \`openrouter-setup <api_key>\`,然后通过 \`model\` 选择模型。自建端点用 \`openrouter-setup <base_url> <api_key>\`。`,parseArgs($){let Z=$.trim().split(/\s+/).filter(Boolean);if(Z.length<1||Z.length>2||Z.length===1&&/^https?:\/\//i.test(Z[0]))return{error:"用法: openrouter-setup <api_key> 或 openrouter-setup <base_url> <api_key>"};try{return{config:{agent:"claude",api_key:Z[Z.length-1],...Z.length===2?{base_url:L4(Z[0])}:{}}}}catch(J){return{error:QJ(J)}}},async validate($){await Bz($.base_url??Wz,$.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=L4(Z);if(new URL(Q).hostname!=="openrouter.ai")return null;return{base_url:Q,api_key:J}}catch{return null}}}})});function GF($){return $.trim().replace(/\[1m\]$/,"").toLowerCase().split("/").at(-1)??""}function Lz($,Z="packy"){return zF[Z].includes(GF($))}var qz,zF;var Pz=R(()=>{qz=["minimax-m3","claude-opus-5","claude-fable-5-1","qwen3.8-max-0902"],zF={packy:qz,"packy-secondary":qz,"packy-codex":["kimi-k3","grok-4.6"]}});function VJ($){return $.replace(/\[1m\]$/,"")==="gemini-3.8-flash"}function WF($,Z,J){let Q=Z==="claude"?s4:Q9,Y=$.reasoning?.supported_efforts;if(Y!==void 0&&(!Array.isArray(Y)||!Y.length||!Y.every((z)=>typeof z==="string")))throw Error(`PackyAPI ${$.id} 的推理档位声明无效`);let V=Y===void 0?[...Q]:Q.filter((z)=>Y.includes(z));if(!V.length)throw Error(`PackyAPI ${$.id} 未声明当前 Agent 可用的推理档位`);let X=J.effort?.trim(),H=X||$.reasoning?.default_effort||(Y===void 0?Z==="claude"?"default":"medium":void 0);if(X&&!V.includes(X))throw Error(`PackyAPI effort 无效: ${X}`);return{model:$.id,display:$.display,efforts:V,defaultEffort:typeof H==="string"&&V.includes(H)?H:null}}var YJ="LODESTAR_PACKY_API_KEY",Dz,Fz;var Mz=R(()=>{B0();j1();dZ();Pz();o$();I();s$();Q0();Dz={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"};Fz=[{id:"packy",agent:"claude",display:"PackyAPI"},{id:"packy-secondary",agent:"claude",display:"PackyAPI · 令牌2"},{id:"packy-codex",agent:"codex",display:"PackyAPI"}];for(let $ of Fz){let{id:Z,agent:J,display:Q}=$,Y=J==="claude"?"anthropic":"openai-response",V=(X)=>X.protocols.includes(Y)||J==="claude"&&VJ(X.id);L0({kind:Z,configSectionId:Z,build(X){let H=X.api_key?.trim()||X.auth_token?.trim()||"",z=f$(X.base_url?.trim()||J2),G=X.management_url?.trim()?f$(X.management_url):_4(z),W=X.management_token?.trim()||"",K=X.management_user_id?.trim()||"",_=!!(W||K||X.management_url?.trim()||X.billing_source?.trim()),j=X.model?.trim(),L=X.models===void 0?void 0:s(X.models),q=new Set([...s(X.custom_models),...L??[]]),D=(O)=>Lz(O,Z),F=[],M=(O)=>{let A=F.find((T)=>T.id===O);if(A&&!V(A)&&!q.has(O))throw Error(`PackyAPI ${O} 未声明 ${Y};确认兼容后可显式补录`)},U={id:Z,kind:Z,agent:J,display:X.display?.trim()||Q,enabled:!!H&&X.enabled!==!1,models:[],defaultModel:j??"",modelSelection:{mode:"allowlist",modelIds:L??[],availableModels:[]},..._?{usageAccount:{id:K$("packy-account",G,K),label:"PackyAPI"}}:{},modelCatalogState:{status:H&&X.enabled!==!1?"idle":"disabled",updatedAt:Date.now()},...J==="claude"?{modelEnvironmentRevision(O){return VJ(O)?JSON.stringify(Dz):"native-retries"}}:{},...J==="codex"?{codexApiProvider:{id:"packy",name:"PackyAPI",baseUrl:`${z}/v1`,envKey:YJ}}:{},async refreshModels(){if(U.models=[],F=[],!U.enabled){U.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}U.modelCatalogState={status:"loading",updatedAt:null};try{F=await lZ(z,H);let O=F.filter((S)=>V(S)||q.has(S.id));if(!O.length&&!q.size)throw Error(`PackyAPI 此令牌没有声明支持 ${Y} 的模型,请检查分组和模型限制`);let A=O.map((S)=>({...WF(S,J,X),...!S.protocols.includes(Y)&&q.has(S.id)?{origin:"custom"}:{}}));for(let S of q){if(A.some((h)=>h.model.toLowerCase()===S.toLowerCase()))continue;A.push({model:S,display:S,origin:"custom",...i1(U,X)})}if(j&&!A.some((S)=>S.model===j)){if(F.find((h)=>h.id===j))throw Error(`PackyAPI ${j} 未声明 ${Y},确认兼容后请显式补录`);if(!q.has(j))throw Error(`PackyAPI 默认模型不在目录中且未补录: ${j}`)}let T=L??A.filter((S)=>S.origin==="custom"||D(S.model)).map((S)=>S.model);if(L===void 0&&j&&!T.some((S)=>S.toLowerCase()===j.toLowerCase()))T.unshift(j);let y=T.map((S)=>A.find((h)=>h.model===S)??{model:S,display:S,efforts:[],defaultEffort:null,unavailableReason:"账号目录未返回该模型"});U.modelSelection.availableModels=A,U.models=y,U.modelSelection.modelIds=y.map((S)=>S.model),U.defaultModel=j??y.find((S)=>!S.unavailableReason)?.model??[...q][0]??"",U.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(O){U.models=[],F=[];let A=p0(O,[H]);B(`${Z} refreshModels MISS: ${A}`),U.modelCatalogState={status:"failed",updatedAt:Date.now(),error:A}}},resolveSpawnModel(O){return M(O),O},spawnEnv(O,A){if(!H)throw Error("PackyAPI API key missing");let T=A||U.defaultModel;if(!T)throw Error("PackyAPI 尚未选择模型");M(T);let y=l0(O);if(delete y[YJ],J==="codex"){for(let h 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 y[h];return y[YJ]=H,y}if(y.ANTHROPIC_BASE_URL=z,y.ANTHROPIC_AUTH_TOKEN=H,y.ANTHROPIC_API_KEY="",y.CLAUDE_CODE_NO_MODEL_FALLBACK="1",VJ(T))Object.assign(y,Dz);y.ANTHROPIC_MODEL=T,y.ANTHROPIC_SMALL_FAST_MODEL=T,y.CLAUDE_CODE_SUBAGENT_MODEL=T;for(let h of["OPUS","SONNET","HAIKU","FABLE"])y[`ANTHROPIC_DEFAULT_${h}_MODEL`]=T;let S={opus:"OPUS",sonnet:"SONNET",haiku:"HAIKU",fable:"FABLE"};for(let h of s(X.slots)){let[l,E,m]=h.split("=");if(!l||!Object.hasOwn(S,l)||!E||m!==void 0)throw Error(`PackyAPI slots 无效: ${h}`);if(!D1(U).some((Y0)=>Y0.model===E))throw Error(`PackyAPI slot 模型不在当前来源: ${E}`);M(E),y[`ANTHROPIC_DEFAULT_${S[l]}_MODEL`]=E}return y},readUsage(){return _?uZ(G,W,K):oH(z,H)}};return U},setup:{commandSuffix:Z,hint:()=>`发送 \`${Z}-setup [base_url] <api_key>\` 配置${Q}。${Z==="packy-codex"?"与 PackyAPI 主账号共用凭据。":""}`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length<1||H.length>2||/^https?:\/\//i.test(H.at(-1)))return{error:`用法: ${Z}-setup [base_url] <api_key>`};try{return{config:{agent:J,api_key:H.at(-1),base_url:f$(H.length===2?H[0]:J2)}}}catch(z){return{error:p0(z,[H.at(-1)])}}},async validate(X){if(!(await lZ(X.base_url??J2,X.api_key??X.auth_token??"")).some(V)&&!s(X.custom_models).length&&!s(X.models).length)throw Error(`此令牌没有声明支持 ${Y} 的模型`)}},...Z==="packy-codex"?{}:{usageSetup:{commandSuffix:`${Z}-balance`,hint:()=>`发送 \`${Z}-balance-setup [management_url] <user_id> <system_token>\` 配置真实余额;共用已有账号用 \`${Z}-balance-setup share <source_id>\`。`,parseArgs(X){let H=X.trim().split(/\s+/).filter(Boolean);if(H.length===2&&H[0]==="share"){if(!Fz.some((W)=>W.id===H[1])||H[1]===Z)return{error:"请指定另一个已配置的 PackyAPI 来源:packy、packy-secondary 或 packy-codex"};return{config:{billing_source:H[1],management_token:"",management_user_id:"",management_url:""}}}if(H.length<2||H.length>3)return{error:`用法:${Z}-balance-setup [management_url] <user_id> <system_token>,或 ${Z}-balance-setup share <source_id>`};let z=H.at(-2),G=H.at(-1);if(!/^[1-9]\d*$/.test(z)||!Number.isSafeInteger(Number(z)))return{error:"用户 ID 必须是正整数"};try{return{config:{billing_source:"",management_token:G,management_user_id:z,management_url:H.length===3?f$(H[0]):""}}}catch(W){return{error:p0(W,[G])}}},async validate(X){let H=X.management_url||_4(X.base_url||J2),z=await uZ(H,X.management_token||"",X.management_user_id||"",!0);if(z.state!=="ok")throw Error(z.reason||"PackyAPI 真实账户余额查询失败")}}}})}});var Uz=1;import{EventEmitter as KF}from"node:events";import{createRequire as BF}from"node:module";import{createHash as _F,randomUUID as jF}from"node:crypto";import{createInterface as qF}from"node:readline";import{dirname as LF,join as $1,isAbsolute as PF}from"node:path";import{fileURLToPath as XJ}from"node:url";import{tmpdir as DF}from"node:os";import{existsSync as Oz,mkdirSync as Az,mkdtempSync as FF,readFileSync as C9,renameSync as MF,writeFileSync as Nz,rmSync as HJ}from"node:fs";import UF from"cross-spawn";function OF($){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 AF($,Z){if(Z?.loadProjectMcp===!1)return[];let J;try{J=C9($1($,".mcp.json"),"utf8")}catch(Y){if(Y?.code==="ENOENT")return[];throw Y}let Q=JSON.parse(J);if(!Q.mcpServers||typeof Q.mcpServers!=="object"||Array.isArray(Q.mcpServers))throw Error("DSH project .mcp.json must contain an mcpServers object");return Object.entries(Q.mcpServers).map(([Y,V])=>{if(!/^[A-Za-z0-9_-]{1,32}$/.test(Y)||!V||typeof V!=="object")throw Error(`invalid DSH MCP server: ${Y}`);let X=V,H=X.type==="http"?{transport:"streamable-http",serverName:Y,url:X.url,headers:X.headers??{}}:X.type===void 0||X.type==="stdio"?{transport:"stdio",serverName:Y,command:X.command,args:X.args??[],env:X.env??{},cwd:$}:null;if(!H)throw Error(`DSH does not support MCP transport ${X.type} for ${Y}`);return{id:`lodestar-mcp-${Y}`,name:"@deepseek-ai/dsh-mcp-client",config:{...H,failOnStartupError:!0}}})}async function P4($,Z,J={}){let Q=new $6($);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 $6;var b9=R(()=>{V0();h2();I();$6=class $6 extends KF{child;pending=new Map;nextId=0;exited=!1;closing=!1;stderr="";initialized=!1;initTask;closeTask;exitTask;launchDir;constructor($){super();if(!PF($.cwd))throw Error("DSH requires an absolute workspace");let Z=p3("dsh"),Q=BF($1(Z,"package.json")).resolve("@deepseek-ai/dsh/package.json"),Y=JSON.parse(C9(Q,"utf8"));B(`dsh runtime: ${Y.version} (${Z})`);let V=OF($.env),X=$.home??E2;Az(X,{recursive:!0,mode:448});let H=AF($.cwd,$.profile);this.launchDir=FF($1(DF(),"lodestar-dsh-"));let z=import.meta.url.endsWith(".ts"),G=z?"dsh-bridge.ts":"dsh-bridge.js",W=C9(XJ(new URL(`./${G}`,import.meta.url))),K=z?C9(XJ(new URL("./dsh-protocol.ts",import.meta.url))):Buffer.alloc(0),_=JSON.parse(C9(XJ(new URL("../package.json",import.meta.url)),"utf8")),j=Buffer.from(JSON.stringify({name:_.name,version:_.version,type:"module",private:!0})),L=_F("sha256").update(W).update(K).update(j).digest("hex").slice(0,20),q=$1(Z,".lodestar-bridges",L);Az(q,{recursive:!0});let D=$1(q,G),F=(S,h)=>{if(Oz(S))return;let l=`${S}.${jF()}.tmp`;try{Nz(l,h),MF(l,S)}finally{if(Oz(l))HJ(l)}};if(F($1(q,"package.json"),j),z)F($1(q,"dsh-protocol.ts"),K);F(D,W);let M=[...["sdk-jsonrpc-server","session-title-llm","session-telemetry-otel","settings","credentials","llm-pi-ai"].map((S)=>({id:S,disabled:!0})),{id:"approval",config:{policy:"ask"}},{id:"permission",config:{defaultPreset:"lodestar",presets:{lodestar:{sandbox:"danger-full-access",approval:"ask"}}}},{id:"system-prompt",config:{personaPrefix:"You are a coding agent powered by {{model}}.",personaSuffix:"Your working directory is {{cwd}}."}},{id:"skill-filesystem",config:{includeDefaultRoots:!0,...$.managedSkillDir?{customSkillDirs:[$.managedSkillDir]}:{}}},{insert:[{id:"lodestar-bridge",name:D},{id:"lodestar-ask-user",name:"@deepseek-ai/dsh-tool-ask-user"},...H]},...V],U=$1(this.launchDir,"bridge.patch.yml");Nz(U,JSON.stringify(M),{mode:384});let O=$.env.LODESTAR_DSH_NODE||"node",A=[$1(LF(Q),Y.bin.dsh),"--profile","sdk","--patch",U,...($.patches??[]).flatMap((S)=>["--patch",S])],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 S of Object.keys(T))if(S.startsWith("LODESTAR_AGENT_"))delete T[S];try{this.child=UF(O,A,{cwd:$.cwd,stdio:["pipe","pipe","pipe"],shell:!1,env:{...T,DSH_HOME:X,DSH_PERMISSION_MODE:"danger-full-access"}})}catch(S){throw HJ(this.launchDir,{recursive:!0,force:!0}),S}this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",(S)=>{this.stderr=(this.stderr+S).slice(-16384),B(`dsh stderr: ${S.trimEnd()}`)}),this.child.stdin.on("error",(S)=>this.transportFailure(S));let y=qF({input:this.child.stdout,crlfDelay:1/0});y.on("line",(S)=>this.receive(S)),this.exitTask=new Promise((S)=>{this.child.once("error",(h)=>this.transportFailure(h)),this.child.once("close",(h,l)=>{this.exited=!0,y.close();let E=Error(`DSH exited code=${h} signal=${l}
115
+ ${this.stderr}`);this.rejectPending(E),HJ(this.launchDir,{recursive:!0,force:!0}),S(),this.emit("exit",{code:h,signal:l,expected:this.closing})})})}get pid(){return this.child.pid}isAlive(){return!this.exited}initialize(){return this.initTask??=this.request("initialize",{},30000).then(($)=>{if($.protocolVersion!==Uz||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
116
  ${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})+`
117
- `,(H)=>{if(H)this.transportFailure(H)})})}receive($){try{let Z=JSON.parse($);if(Z.jsonrpc!=="2.0")throw Error("invalid DSH JSON-RPC envelope");if(typeof Z.id==="number"){let J=this.pending.get(Z.id);if(!J){B(`dsh: unexpected response id=${Z.id}`);return}if(this.pending.delete(Z.id),clearTimeout(J.timer),Z.error)J.reject(Error(`DSH RPC error: ${Z.error.message}`));else if("result"in Z)J.resolve(Z.result);else J.reject(Error("DSH response has neither result nor error"))}else if(typeof Z.method==="string"&&Z.params&&typeof Z.params==="object")this.emit("notification",{method:Z.method,params:Z.params});else throw Error("invalid DSH notification")}catch(Z){this.transportFailure(Z instanceof Error?Z:Error(String(Z)))}}rejectPending($){for(let Z of this.pending.values())clearTimeout(Z.timer),Z.reject($);this.pending.clear()}transportFailure($){this.rejectPending($),this.emit("failure",$)}close($=3000){return this.closeTask??=this.dispose($).catch((Z)=>{throw this.closeTask=void 0,Z})}async dispose($){if(this.exited)return;if(this.closing=!0,this.initialized)try{await this.request("shutdown",{},$)}catch(J){B(`dsh shutdown: ${J}`)}this.child.stdin.end();let Z=async(J)=>{let Q;return await Promise.race([this.exitTask,new Promise((Y)=>{Q=setTimeout(Y,J)})]),clearTimeout(Q),this.exited};if(await Z($))return;if(B(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(B(`dsh: kill unresponsive owned child pid=${this.pid}`),this.child.kill("SIGKILL"),!await Z($))throw Error(`DSH child exit not confirmed: pid=${this.pid}`)}}});var Rz=R(()=>{Q0();B0();b9();V0();$J();o$();L0({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=H9(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 P4({cwd:E2,env:Q.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...s($.models),...s($.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(F0)||!F0(X.defaultEffort)||!X.efforts.includes(X.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${X.model}`);let V=$.model?.trim()||Y.find((X)=>X.isDefault)?.model;if(!V||!Y.some((X)=>X.model===V))throw Error("DSH default model is not in its catalog");Q.models=Y.map(({model:X,display:H,efforts:z,defaultEffort:G,isCustom:W})=>{let K=$.effort?.trim();if(K&&(!F0(K)||!z.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:H,efforts:z,defaultEffort:K?K:G,origin:W?"custom":"upstream"}}),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 D1(Q).find((V)=>V.model===Y)?.model},readUsage(){return Z?eZ(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 rZ($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function Z6($){let Z=new URL($);if(!Z2(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 Tz($,Z){return(await S$(`${$}/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 xz=R(()=>{k2();f0();B0();Q0();b9();V0();l8();sZ();o$();L0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=p.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Q=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Q&&Z2(Q)?{api_key:J,base_url:Z6(Q)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Q=Z6($.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((H)=>H.model).sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(H){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=H9(H);z.LODESTAR_DSH_PROVIDER=Y,z.LODESTAR_DSH_GLM_API_KEY=J,z.LODESTAR_DSH_BASE_URL=Q,z.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel;let G=(X.modelSelection?.availableModels??X.models).map((W)=>W.model);if(V||G.length)z.LODESTAR_DSH_MODELS=JSON.stringify(V??G);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(X.models=[],V=void 0,!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let H=await Tz(Q,J),z=[...H];for(let W of[...s($.models),...s($.custom_models)])if(!z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))z.push({model:W,display:W});if(V=z.map((W)=>W.model),!$.model?.trim()){let W=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...H].sort((K,_)=>W(_.model)-W(K.model))[0].model}let G=await P4({cwd:E2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=z.map((W)=>{let K=G.find((q)=>q.model===W.model),_=i1(X,$),j=K?K.efforts.filter(F0):_.efforts,L=$.effort?.trim()||K?.defaultEffort||_.defaultEffort;return{...W,display:K?.display??W.display,efforts:j,defaultEffort:F0(L)&&j.includes(L)?L:null,origin:H.some((q)=>q.model===W.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H instanceof Error?H.message:String(H)},H}},resolveSpawnModel(H){return D1(X).find((z)=>z.model===H&&!z.unavailableReason)?.model},async readUsage(){return J?oZ(await c8(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:Z6(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 Tz(Z6($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var Cz={};d$(Cz,{tokenSourceSpawnRevision:()=>Sz,buildTokenSourcesFromConfig:()=>k9});import{createHash as Ez}from"node:crypto";function k9(){let $=cZ(),Z=Object.fromEntries(a1().flatMap((G)=>{let W=G.detect?.fromSettingsEnv($);return G.configSectionId&&W?[[G.configSectionId,W]]:[]})),J=E9(p.token_sources??{},Z),Q=new Map(u0().map((G)=>[G.id,G])),Y=a1().map((G)=>{let W=G.configSectionId?J[G.configSectionId]??{}:{},K=G.configSectionId?Z[G.configSectionId]??null:null,_=()=>{let j=X8(G.build(W,K),W);return j.spawnRevision=Sz(G.kind,W,K),j};return{cfg:W,detected:K,create:_,initial:_()}}),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:_})=>{let j=()=>{let F=K();if(F.kind==="claude-native")F.enabled=!V,F.modelCatalogState={status:F.enabled?"idle":"disabled",updatedAt:Date.now()};return F},L=(F)=>{let{display:U,model:M,effort:O,models:A,hidden_models:T,custom_models:y,slots:S,default:h,...l}=F??{};return l},q=(F)=>Ez("sha256").update(JSON.stringify(F,(U,M)=>M&&typeof M==="object"&&!Array.isArray(M)?Object.fromEntries(Object.entries(M).sort(([O],[A])=>O.localeCompare(A))):M)).digest("hex"),D=_.kind==="claude-native"?!V:void 0;return n5(j,G,q([_.id,L(G),L(W),D]),q([G,W,D]),Q.get(_.id))});h5();for(let G of X)y5(G);for(let G of Q.values())if(!X.includes(G))q9(G);let z=X.find((G)=>G.enabled&&p.token_sources?.[G.id]?.default===!0)??X.find((G)=>G.enabled);if(z)f5(z.id);return X.length}function Sz($,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 Ez("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var J6=R(()=>{f0();Q0();l8();o$();S9();A8();M8();sZ();$z();Vz();$J();jz();Uz();Rz();xz()});function zJ($){let Z=new Map,J=$.map((W)=>{let K=W.fingerprint?Z.get(W.fingerprint):void 0;if(W.fingerprint&&!K)Z.set(W.fingerprint,W.account.name);return{...W,...K?{duplicateOf:K}:{}}}),Q=J.filter((W)=>!W.duplicateOf),V=(Q.length<=1||Q.every((W)=>W.fingerprint!==null))&&Q.every((W)=>W.usage.state==="ok"),X=Q.flatMap((W)=>W.usage.state==="ok"?[W.usage]:[]),H=V&&X.every((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent!==null))?X.filter((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,z=V&&X.every((W)=>W.resetCredits!=null)?X.reduce((W,K)=>W+K.resetCredits,0):null,G=["fiveHour","weekly"].map((W)=>{let K=X.map((j)=>j[W]).filter((j)=>j!==null),_=V&&K.every((j)=>j.percent!==null&&j.percent>=0&&j.percent<=100);return{kind:W,count:K.length,remaining:_?K.reduce((j,L)=>j+(100-L.percent)/100,0):null}}).filter((W)=>W.count||!V);return{entries:J,complete:V,available:H,resetCredits:z,windows:G}}async function bz($){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 Q6($){let Z=new Map,J=await Promise.all(v.list().map(async(Q)=>{let Y=null;try{Y=v.fingerprint(Q.id)}catch(z){return{account:Q,fingerprint:Y,usage:{state:"network",reason:`账号身份读取失败:${String(z)}`}}}let V=Y??Q.id,X=Z.get(V);if(!X)X=$?.id===Q.id?Promise.resolve($.usage):NX(Q.id),Z.set(V,X);let H=await X;if(H.state==="ok"&&H.accountFingerprint)Y=H.accountFingerprint;return{account:Q,usage:H,fingerprint:Y}}));return zJ(J)}var GJ=R(()=>{D0();U$();I();G8()});import{existsSync as NF,readFileSync as RF}from"node:fs";class kz{deps;lastUses=new Map;constructor($){this.deps=$}recordUsage($,Z){let J=this.deps.cachedUsage($);if(J?.state!=="ok")return;let Q=J.accountFingerprint??this.deps.identity($);if(!Q)return;this.lastUses.set(JSON.stringify([Q,Z8(J,Z)]),this.deps.now())}blocks(){if(!NF(this.deps.stateFile))return[];let $=JSON.parse(RF(this.deps.stateFile,"utf8"));if($?.version!==1||!Array.isArray($.blocks)||$.blocks.some((Z)=>typeof Z?.key!=="string"||typeof Z?.identity!=="string"||typeof Z?.meter!=="string"||!Array.isArray(Z?.windows)||Z.windows.some((J)=>!["fiveHour","weekly"].includes(J?.kind)||J.percent!==null&&!Number.isFinite(J.percent)||J.reset!==null&&!Number.isFinite(J.reset))))throw Error("Codex 额度耗尽记录格式无效");return $.blocks}block($,Z){if(!$.usage)throw Error("未读取额度,不能记录耗尽窗口");let J=$.usage.state==="ok"?d1($.usage,Z):null,Q=["fiveHour","weekly"].flatMap((H)=>{let z=J?.[H];return z?[{kind:H,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Y=Z8($.usage,Z),V=JSON.stringify([$.identity,Y]),X=this.blocks().filter((H)=>H.key!==V);X.push({key:V,identity:$.identity,meter:Y,windows:Q,blockedAt:this.deps.now()}),o(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(q)=>{let D,F=null,U=`record:${q.id}`;if(this.deps.pendingLogin(q.id))D={state:"network",reason:"正在登录"};else try{D=J?this.deps.cachedUsage(q.id):await this.deps.usage(q.id);let M=D?.state==="ok"?D.accountFingerprint??this.deps.identity(q.id):null;if(M)U=M;else if(D?.state==="ok")F="账号身份 MISS";if(D?.state==="ok"&&!F){let O=Q.get(q.id);if(!O)O=this.deps.compatible(q.id,Z.model,Z.effort),Q.set(q.id,O);F=await O}}catch(M){D={state:"network",reason:String(M)}}return{account:q,usage:D,identity:U,reason:F}}));Z.signal?.throwIfAborted();let V=Z.failedAccountId&&Y.find((q)=>q.account.id===Z.failedAccountId);if(V&&V.usage?.state==="ok")this.block({account:V.account,usage:V.usage,identity:V.identity,...R5(V.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let X=this.blocks(),H=this.deps.now(),z=new Set,G=new Map,W=Y.map(({account:q,usage:D,identity:F,reason:U})=>{let M=R5(D??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(U)M={...M,state:"miss",score:null,reason:U};let O=G.get(F);if(G.set(F,O??q.name),O)M={...M,state:"miss",score:null,reason:`重复账号:${O}`};let A=D?.state==="ok"?Z8(D,Z.model):null,T=this.lastUses.get(JSON.stringify([F,A]));if(M.priority==="unused"&&D?.state==="ok"&&T!==void 0&&JX(D,Z.model,T))M={...M,priority:void 0};let y=X.find((S)=>(S.identity===F||S.identity===`record:${q.id}`)&&S.meter===A);if(y&&D?.state==="ok"&&M.state==="ready"){let S=d1(D,Z.model);if((D.readStartedAt??D.fetchedAt)>(y.blockedAt??0)&&y.windows.some((l)=>{let E=S[l.kind];return E&&E.percent!==null&&(l.percent!==null&&E.percent<l.percent||l.reset!==null&&l.reset<=H&&(E.resetsAt?.getTime()??0)>l.reset)}))z.add(y.key);else M={...M,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:q,usage:D,identity:F,...M,...O?{duplicateOf:O}:{}}});if(z.size)o(this.deps.stateFile,{version:1,blocks:X.filter((q)=>!z.has(q.key))});let K=W.filter((q)=>q.state==="ready");K.sort(J8);let _=K[0]??null,j=W.filter((q)=>q.state==="exhausted"||q.state==="waiting"),L=j.length?Math.min(...j.map((q)=>q.retryAt??H+60000)):void 0;for(let q of W)B(`codex scheduler${J?" [cache]":""}: ${q.account.name} ${q.state} priority=${q.priority??"score"} score=${q.score??(q.priority==="expiring"?"N/A":"MISS")}${q.reason?` (${q.reason})`:""}`);return{selected:_,candidates:W,...L!==void 0?{retryAt:L}:{}}}}function TF($,Z,J){let Q=k$($,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 xF($,Z,J,Q=Date.now()){if(!$.enabled||$.modelCatalogState?.status!=="ready")return`模型目录查询失败:${$.modelCatalogState?.error??($.enabled?"模型目录 MISS":"订阅来源未启用")}`;return TF($,Z,J)}var Y6;var WJ=R(()=>{D0();U$();Q0();V0();v0();I();Y6=new kz({accounts:()=>v.list(),usage:async($)=>n1($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"},cachedUsage:X9,identity:($)=>v.fingerprint($),pendingLogin:g2,now:Date.now,stateFile:dY,compatible:async($,Z,J)=>{let Q=G0("codex-sub",$);if(!Q)return"订阅来源 MISS";return xF(Q,Z,J)}})});import{createHash as wz,randomUUID as EF}from"node:crypto";function D4($,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 O$($){let Z=V$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function Y$($){return!V$.has($)}function A$($,Z,J){V$.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 y9($){return V$.get($)?.elementCount??0}function yz($){let Z=V$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function F4($,Z){return V$.get($)?.deadElements.has(Z)??!1}function vz($,Z){let J=V$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function V6($){let Z=O$($);return Z.sequence+=1,Z.sequence}function BJ($,Z){$.deadElements.add(Z)}function fz($){return wz("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function wF($,Z,J){let Q=[...$.contentFingerprints].filter(([Y])=>Y!==Z).map(([,Y])=>Y);if(J&&Z!==C.footer)Q.push(J);return wz("sha256").update(Q.sort().join(`
118
- `)).digest("hex")}async function w9($,Z,J,Q){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:EF()}:{}}):void 0,V=`cardkit ${$} ${Z}`;return p1(V,async()=>{let X=await y$(),H=AbortSignal.timeout(CF),z;try{return z=await X0(`${SF}${Z}`,{method:$,headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:H}),(await z$(z,V))?.data}catch(G){if(H.aborted&&H.reason?.name==="TimeoutError")G=H.reason;if(z&&G instanceof y0)Object.assign(G,{httpStatus:z.status});throw Q?.(G),G}},{api:"cardkit"})}function _J($){return $ instanceof y0&&($.code===200770||$.code==="200770")}function hz($){if(_J($))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 I3($,{api:"cardkit"})}async function X6($,Z,J,Q){let Y=!1;try{await w9(Z,J,{...Q,sequence:V6($)},(V)=>{if(hz(V))Y=!0})}catch(V){if(!Y||!_J(V))throw V;B(`cardkit confirm ${Z} ${J}: ${V}; retrying same state with new UUID and sequence`),await w9(Z,J,{...Q,sequence:V6($)})}}async function Iz($,Z,J,Q){let Y=J.element_id,V=!1;try{await w9("POST",`/cards/${$}/elements`,{type:Q.type??"append",...Q.targetElementId?{target_element_id:Q.targetElementId}:{},elements:JSON.stringify([J]),sequence:V6($)},(X)=>{if(hz(X)){if(V=!0,Y)Z.uncertainAdds.add(Y)}})}catch(X){let H=X,z=Y&&Z.uncertainAdds.has(Y)&&KJ(H?.code,H);if(!Y||!(z||V&&_J(X)))throw X;B(`cardkit reconcile uncertain add ${$} element=${Y}: ${X}; confirming latest content with PUT`),await X6($,"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 yF($){return new Promise((Z)=>setTimeout(Z,$))}function vF($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function fF($){await X6($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}})})}async function H6($,Z,J,Q,Y=!1,V={}){let X=(H)=>{let z=typeof H==="object"&&H!==null?H:null,G={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:H instanceof Error?H.message:String(H),apiMessage:z?.apiMessage};if(D4(G.code,G))G.capacityFingerprint=wF(O$($),V.elementId,V.contentFingerprint);try{if(!Y||Y==="non-capacity"&&D4(G.code,G))O$($).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(H){if(!vF(H)){B(`cardkit ${Z} ${$}: ${H}`),X(H);return}B(`cardkit ${Z} ${$}: streaming closed (code=${H.code}) — reopening`)}try{await fF($)}catch(H){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${H}`),X(H);return}try{await J()}catch(H){B(`cardkit ${Z} ${$} retry-after-reopen: ${H}`),X(H)}}function hF($){return typeof $==="object"&&$!==null&&$.code===200740}async function h$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:bF,Q=null;for(let Y=0;Y<J.length;Y++){let V=J[Y]??0;if(V>0)await yF(V);try{let X=await w9("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,!hF(X)||Y===J.length-1)throw X;let H=J[Y+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${H}ms`)}}throw Q}async function T1($){let Z=V$.get($);if(!Z)return;await Z.queue}function N0($,Z,J={},Q,Y="all"){if(Y$($))return Promise.resolve();let V=O$($);if(V.closing)return Promise.resolve();let X=M1(Z),H=X.element_id,z=fz(X),G=()=>{if(!H)return;BJ(V,H),V.failedAdds.set(H,J)};return V.queue=V.queue.then(()=>H6($,"addElement",async()=>{if(await Iz($,V,X,J),H!==C.footer)V.contentFingerprints.set(H??`#${V.sequence}`,z);if(H)V.deadElements.delete(H),V.failedAdds.delete(H),V.failedReplacements.delete(H)},(W)=>{G(),Q?.(W.code,W)},Y==="capacity"?"non-capacity":!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:z})),V.queue}function P0($,Z,J,Q,Y=!0){if(Y$($))return Promise.resolve();let V=O$($);if(V.closing)return Promise.resolve();let X=M1(J),H=fz(X),z=()=>{BJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>H6($,`replaceElement ${Z}`,async()=>{let G=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!G&&!V.failedReplacements.has(Z))return;if(G)await Iz($,V,X,G);else await X6($,"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,H)},(G)=>{if(Y)z();Q?.(G.code,G)},!Y,{elementId:Z,contentFingerprint:H})),V.queue}async function K0($,Z,J,Q={}){if(Y$($))return!1;let Y=O$($);if(Y.closing)return!1;let V=!1;return await P0($,Z,J,(X,H)=>{if(V=!0,H)Q.onFailure?.(H)},Q.notifyCardFailure!==!1),!V&&!Y.deadElements.has(Z)}async function gz($,Z,J){if(Y$($))return{landed:!1};let Q=O$($);if(Q.closing)return{landed:!1};let Y;return await P0($,Z,J,(V,X)=>{Y=X}),{landed:!Y&&!Q.deadElements.has(Z),...Y?{failure:Y}:{}}}async function X2($,Z,J={}){let Q=await U4($,Z,J);if(Q.failure)J.onFailure?.(Q.failure);return Q.landed}async function U4($,Z,J={}){if(Y$($))return{landed:!1};let Q=O$($);if(Q.closing)return{landed:!1};let Y=Z.element_id,V;return await N0($,Z,J,(X,H)=>{V=H}),{landed:!V&&!(Y&&Q.deadElements.has(Y)),...V?{failure:V}:{}}}function IF($,Z,J){if(Y$($))return Promise.resolve();let Q=O$($);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(()=>H6($,`deleteElement ${Z}`,async()=>{if(Y())return;let V=V6($);await w9("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),BJ(Q,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Q.queue}async function mz($,Z,J){if(Y$($))return!1;let Q=O$($);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 IF($,Z,(V,X)=>{if(Y=!0,X)J?.(X)}),!Y&&Q.deadElements.has(Z)}function M4($,Z){if(Y$($)||V$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=V2.get($);if(!Q)Q={latest:J,lastSent:"",timer:null,inFlight:!1},V2.set($,Q);else{if(Q.latest===J)return;Q.latest=J}pz($,Q)}function pz($,Z){if(Z.timer||Z.inFlight||Z.latest===Z.lastSent)return;Z.timer=setTimeout(()=>{if(V2.get($)!==Z)return;if(Z.timer=null,Y$($)||V$.get($)?.closing){V2.delete($);return}if(Z.latest===Z.lastSent)return;let J=Z.latest;Z.inFlight=!0,C0($,{config:{summary:{content:J}}}).then((Q)=>{if(V2.get($)!==Z)return;if(Z.inFlight=!1,Q)Z.lastSent=J;if(Z.latest!==J&&!Y$($)&&!V$.get($)?.closing)pz($,Z)})},kF)}function i0($){let Z=V2.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;V2.delete($)}function z6($,Z){return C0($,Z).then(()=>{})}async function C0($,Z,J){if(Y$($))return!1;let Q=O$($);if(Q.closing)return!1;let Y=!1,V=!1;return Q.queue=Q.queue.then(()=>H6($,"patchSettings",async()=>{if(Y$($))return;await X6($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z)}),Y=!0},(X)=>{V=!0,J?.(X)},!0)),await Q.queue,Y&&!V&&!Y$($)}async function B$($){let Z=V$.get($);if(!Z){i0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,i0($),await Z.queue,V$.delete($)}var SF="https://open.feishu.cn/open-apis/cardkit/v1",CF=15000,bF,V$,V2,kF=1500;var Z1=R(()=>{o0();e();b2();I();h0();bF=[0,250,750,1500];V$=new Map,V2=new Map});function I$($){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 cz($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(z)=>`&#${z.charCodeAt(0)};`),Q=typeof $.used==="number"&&typeof $.total==="number"?` · ${$.used}/${$.total}`:"",Y=$.percent;if(Y===null||!Number.isFinite(Y)||Y<0||Y>100)return[{tag:"markdown",content:`**${J} · MISS${Q}**`}];let V=Math.round(Y/100*6),X=Y>=100?"red":Y>=80?"orange":"green",H=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${I$($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Y)}%${Q}**
117
+ `,(H)=>{if(H)this.transportFailure(H)})})}receive($){try{let Z=JSON.parse($);if(Z.jsonrpc!=="2.0")throw Error("invalid DSH JSON-RPC envelope");if(typeof Z.id==="number"){let J=this.pending.get(Z.id);if(!J){B(`dsh: unexpected response id=${Z.id}`);return}if(this.pending.delete(Z.id),clearTimeout(J.timer),Z.error)J.reject(Error(`DSH RPC error: ${Z.error.message}`));else if("result"in Z)J.resolve(Z.result);else J.reject(Error("DSH response has neither result nor error"))}else if(typeof Z.method==="string"&&Z.params&&typeof Z.params==="object")this.emit("notification",{method:Z.method,params:Z.params});else throw Error("invalid DSH notification")}catch(Z){this.transportFailure(Z instanceof Error?Z:Error(String(Z)))}}rejectPending($){for(let Z of this.pending.values())clearTimeout(Z.timer),Z.reject($);this.pending.clear()}transportFailure($){this.rejectPending($),this.emit("failure",$)}close($=3000){return this.closeTask??=this.dispose($).catch((Z)=>{throw this.closeTask=void 0,Z})}async dispose($){if(this.exited)return;if(this.closing=!0,this.initialized)try{await this.request("shutdown",{},$)}catch(J){B(`dsh shutdown: ${J}`)}this.child.stdin.end();let Z=async(J)=>{let Q;return await Promise.race([this.exitTask,new Promise((Y)=>{Q=setTimeout(Y,J)})]),clearTimeout(Q),this.exited};if(await Z($))return;if(B(`dsh: terminate owned child pid=${this.pid}`),this.child.kill("SIGTERM"),await Z($))return;if(B(`dsh: kill unresponsive owned child pid=${this.pid}`),this.child.kill("SIGKILL"),!await Z($))throw Error(`DSH child exit not confirmed: pid=${this.pid}`)}}});var Rz=R(()=>{Q0();B0();b9();V0();$J();o$();L0({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=H9(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 P4({cwd:E2,env:Q.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list",{models:[...s($.models),...s($.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(F0)||!F0(X.defaultEffort)||!X.efforts.includes(X.defaultEffort))throw Error(`Invalid DSH model/effort catalog: ${X.model}`);let V=$.model?.trim()||Y.find((X)=>X.isDefault)?.model;if(!V||!Y.some((X)=>X.model===V))throw Error("DSH default model is not in its catalog");Q.models=Y.map(({model:X,display:H,efforts:z,defaultEffort:G,isCustom:W})=>{let K=$.effort?.trim();if(K&&(!F0(K)||!z.includes(K)))throw Error(`DSH model ${X} does not support configured effort ${K}`);return{model:X,display:H,efforts:z,defaultEffort:K?K:G,origin:W?"custom":"upstream"}}),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 D1(Q).find((V)=>V.model===Y)?.model},readUsage(){return Z?eZ(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 rZ($.base_url??"https://api.deepseek.com",$.api_key??"")}}})});function Z6($){let Z=new URL($);if(!Z2(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 Tz($,Z){return(await S$(`${$}/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 xz=R(()=>{k2();f0();B0();Q0();b9();V0();l8();sZ();o$();L0({kind:"dsh-glm",configSectionId:"dsh-glm",detect:{fromSettingsEnv($){let Z=p.token_sources?.glm,J=Z?.auth_token?.trim()||$.ANTHROPIC_AUTH_TOKEN?.trim(),Q=Z?.base_url?.trim()||$.ANTHROPIC_BASE_URL?.trim();return J&&Q&&Z2(Q)?{api_key:J,base_url:Z6(Q)}:null}},build($,Z){let J=$.api_key?.trim()||$.auth_token?.trim()||Z?.api_key?.trim()||"",Q=Z6($.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((H)=>H.model).sort())},modelCatalogState:{status:J?"idle":"disabled",updatedAt:Date.now()},spawnEnv(H){if(!J)throw Error("DSH GLM Coding Plan API key is missing");let z=H9(H);z.LODESTAR_DSH_PROVIDER=Y,z.LODESTAR_DSH_GLM_API_KEY=J,z.LODESTAR_DSH_BASE_URL=Q,z.LODESTAR_DSH_DEFAULT_MODEL=X.defaultModel;let G=(X.modelSelection?.availableModels??X.models).map((W)=>W.model);if(V||G.length)z.LODESTAR_DSH_MODELS=JSON.stringify(V??G);if($.bin)z.LODESTAR_DSH_NODE=$.bin;return z},async refreshModels(){if(X.models=[],V=void 0,!X.enabled){X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let H=await Tz(Q,J),z=[...H];for(let W of[...s($.models),...s($.custom_models)])if(!z.some((K)=>K.model.toLowerCase()===W.toLowerCase()))z.push({model:W,display:W});if(V=z.map((W)=>W.model),!$.model?.trim()){let W=(K)=>Number(K.match(/\d+(?:\.\d+)?/)?.[0]??-1);X.defaultModel=[...H].sort((K,_)=>W(_.model)-W(K.model))[0].model}let G=await P4({cwd:E2,env:X.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"model/list");X.models=z.map((W)=>{let K=G.find((q)=>q.model===W.model),_=i1(X,$),j=K?K.efforts.filter(F0):_.efforts,L=$.effort?.trim()||K?.defaultEffort||_.defaultEffort;return{...W,display:K?.display??W.display,efforts:j,defaultEffort:F0(L)&&j.includes(L)?L:null,origin:H.some((q)=>q.model===W.model)?"upstream":"custom"}}),X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(H){throw X.models=[],V=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:H instanceof Error?H.message:String(H)},H}},resolveSpawnModel(H){return D1(X).find((z)=>z.model===H&&!z.unavailableReason)?.model},async readUsage(){return J?oZ(await c8(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:Z6(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 Tz(Z6($.base_url??"https://open.bigmodel.cn/api/coding/paas/v4"),$.api_key??$.auth_token??"")}}})});var Cz={};d$(Cz,{tokenSourceSpawnRevision:()=>Sz,buildTokenSourcesFromConfig:()=>k9});import{createHash as Ez}from"node:crypto";function k9(){let $=cZ(),Z=Object.fromEntries(a1().flatMap((G)=>{let W=G.detect?.fromSettingsEnv($);return G.configSectionId&&W?[[G.configSectionId,W]]:[]})),J=E9(p.token_sources??{},Z),Q=new Map(u0().map((G)=>[G.id,G])),Y=a1().map((G)=>{let W=G.configSectionId?J[G.configSectionId]??{}:{},K=G.configSectionId?Z[G.configSectionId]??null:null,_=()=>{let j=X8(G.build(W,K),W);return j.spawnRevision=Sz(G.kind,W,K),j};return{cfg:W,detected:K,create:_,initial:_()}}),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:_})=>{let j=()=>{let F=K();if(F.kind==="claude-native")F.enabled=!V,F.modelCatalogState={status:F.enabled?"idle":"disabled",updatedAt:Date.now()};return F},L=(F)=>{let{display:M,model:U,effort:O,models:A,hidden_models:T,custom_models:y,slots:S,default:h,...l}=F??{};return l},q=(F)=>Ez("sha256").update(JSON.stringify(F,(M,U)=>U&&typeof U==="object"&&!Array.isArray(U)?Object.fromEntries(Object.entries(U).sort(([O],[A])=>O.localeCompare(A))):U)).digest("hex"),D=_.kind==="claude-native"?!V:void 0;return n5(j,G,q([_.id,L(G),L(W),D]),q([G,W,D]),Q.get(_.id))});h5();for(let G of X)y5(G);for(let G of Q.values())if(!X.includes(G))q9(G);let z=X.find((G)=>G.enabled&&p.token_sources?.[G.id]?.default===!0)??X.find((G)=>G.enabled);if(z)f5(z.id);return X.length}function Sz($,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 Ez("sha256").update(JSON.stringify({kind:$,configured:Q(Z),detected:Q(J)})).digest("hex")}var J6=R(()=>{f0();Q0();l8();o$();S9();A8();U8();sZ();$z();Vz();$J();jz();Mz();Rz();xz()});function zJ($){let Z=new Map,J=$.map((W)=>{let K=W.fingerprint?Z.get(W.fingerprint):void 0;if(W.fingerprint&&!K)Z.set(W.fingerprint,W.account.name);return{...W,...K?{duplicateOf:K}:{}}}),Q=J.filter((W)=>!W.duplicateOf),V=(Q.length<=1||Q.every((W)=>W.fingerprint!==null))&&Q.every((W)=>W.usage.state==="ok"),X=Q.flatMap((W)=>W.usage.state==="ok"?[W.usage]:[]),H=V&&X.every((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent!==null))?X.filter((W)=>[W.fiveHour,W.weekly].filter(Boolean).every((K)=>K.percent<100)).length:null,z=V&&X.every((W)=>W.resetCredits!=null)?X.reduce((W,K)=>W+K.resetCredits,0):null,G=["fiveHour","weekly"].map((W)=>{let K=X.map((j)=>j[W]).filter((j)=>j!==null),_=V&&K.every((j)=>j.percent!==null&&j.percent>=0&&j.percent<=100);return{kind:W,count:K.length,remaining:_?K.reduce((j,L)=>j+(100-L.percent)/100,0):null}}).filter((W)=>W.count||!V);return{entries:J,complete:V,available:H,resetCredits:z,windows:G}}async function bz($){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 Q6($){let Z=new Map,J=await Promise.all(v.list().map(async(Q)=>{let Y=null;try{Y=v.fingerprint(Q.id)}catch(z){return{account:Q,fingerprint:Y,usage:{state:"network",reason:`账号身份读取失败:${String(z)}`}}}let V=Y??Q.id,X=Z.get(V);if(!X)X=$?.id===Q.id?Promise.resolve($.usage):NX(Q.id),Z.set(V,X);let H=await X;if(H.state==="ok"&&H.accountFingerprint)Y=H.accountFingerprint;return{account:Q,usage:H,fingerprint:Y}}));return zJ(J)}var GJ=R(()=>{D0();M$();I();G8()});import{existsSync as NF,readFileSync as RF}from"node:fs";class kz{deps;lastUses=new Map;constructor($){this.deps=$}recordUsage($,Z){let J=this.deps.cachedUsage($);if(J?.state!=="ok")return;let Q=J.accountFingerprint??this.deps.identity($);if(!Q)return;this.lastUses.set(JSON.stringify([Q,Z8(J,Z)]),this.deps.now())}blocks(){if(!NF(this.deps.stateFile))return[];let $=JSON.parse(RF(this.deps.stateFile,"utf8"));if($?.version!==1||!Array.isArray($.blocks)||$.blocks.some((Z)=>typeof Z?.key!=="string"||typeof Z?.identity!=="string"||typeof Z?.meter!=="string"||!Array.isArray(Z?.windows)||Z.windows.some((J)=>!["fiveHour","weekly"].includes(J?.kind)||J.percent!==null&&!Number.isFinite(J.percent)||J.reset!==null&&!Number.isFinite(J.reset))))throw Error("Codex 额度耗尽记录格式无效");return $.blocks}block($,Z){if(!$.usage)throw Error("未读取额度,不能记录耗尽窗口");let J=$.usage.state==="ok"?d1($.usage,Z):null,Q=["fiveHour","weekly"].flatMap((H)=>{let z=J?.[H];return z?[{kind:H,percent:z.percent,reset:z.resetsAt?.getTime()??null}]:[]}),Y=Z8($.usage,Z),V=JSON.stringify([$.identity,Y]),X=this.blocks().filter((H)=>H.key!==V);X.push({key:V,identity:$.identity,meter:Y,windows:Q,blockedAt:this.deps.now()}),o(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(q)=>{let D,F=null,M=`record:${q.id}`;if(this.deps.pendingLogin(q.id))D={state:"network",reason:"正在登录"};else try{D=J?this.deps.cachedUsage(q.id):await this.deps.usage(q.id);let U=D?.state==="ok"?D.accountFingerprint??this.deps.identity(q.id):null;if(U)M=U;else if(D?.state==="ok")F="账号身份 MISS";if(D?.state==="ok"&&!F){let O=Q.get(q.id);if(!O)O=this.deps.compatible(q.id,Z.model,Z.effort),Q.set(q.id,O);F=await O}}catch(U){D={state:"network",reason:String(U)}}return{account:q,usage:D,identity:M,reason:F}}));Z.signal?.throwIfAborted();let V=Z.failedAccountId&&Y.find((q)=>q.account.id===Z.failedAccountId);if(V&&V.usage?.state==="ok")this.block({account:V.account,usage:V.usage,identity:V.identity,...R5(V.usage,Z.model,this.deps.now(),Z.effort)},Z.model);let X=this.blocks(),H=this.deps.now(),z=new Set,G=new Map,W=Y.map(({account:q,usage:D,identity:F,reason:M})=>{let U=R5(D??{state:"network",reason:"尚无额度缓存"},Z.model,H,Z.effort);if(M)U={...U,state:"miss",score:null,reason:M};let O=G.get(F);if(G.set(F,O??q.name),O)U={...U,state:"miss",score:null,reason:`重复账号:${O}`};let A=D?.state==="ok"?Z8(D,Z.model):null,T=this.lastUses.get(JSON.stringify([F,A]));if(U.priority==="unused"&&D?.state==="ok"&&T!==void 0&&JX(D,Z.model,T))U={...U,priority:void 0};let y=X.find((S)=>(S.identity===F||S.identity===`record:${q.id}`)&&S.meter===A);if(y&&D?.state==="ok"&&U.state==="ready"){let S=d1(D,Z.model);if((D.readStartedAt??D.fetchedAt)>(y.blockedAt??0)&&y.windows.some((l)=>{let E=S[l.kind];return E&&E.percent!==null&&(l.percent!==null&&E.percent<l.percent||l.reset!==null&&l.reset<=H&&(E.resetsAt?.getTime()??0)>l.reset)}))z.add(y.key);else U={...U,state:"exhausted",score:null,reason:"上次请求已确认额度耗尽,等待接口确认恢复"}}return{account:q,usage:D,identity:F,...U,...O?{duplicateOf:O}:{}}});if(z.size)o(this.deps.stateFile,{version:1,blocks:X.filter((q)=>!z.has(q.key))});let K=W.filter((q)=>q.state==="ready");K.sort(J8);let _=K[0]??null,j=W.filter((q)=>q.state==="exhausted"||q.state==="waiting"),L=j.length?Math.min(...j.map((q)=>q.retryAt??H+60000)):void 0;for(let q of W)B(`codex scheduler${J?" [cache]":""}: ${q.account.name} ${q.state} priority=${q.priority??"score"} score=${q.score??(q.priority==="expiring"?"N/A":"MISS")}${q.reason?` (${q.reason})`:""}`);return{selected:_,candidates:W,...L!==void 0?{retryAt:L}:{}}}}function TF($,Z,J){let Q=k$($,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 xF($,Z,J,Q=Date.now()){if(!$.enabled||$.modelCatalogState?.status!=="ready")return`模型目录查询失败:${$.modelCatalogState?.error??($.enabled?"模型目录 MISS":"订阅来源未启用")}`;return TF($,Z,J)}var Y6;var WJ=R(()=>{D0();M$();Q0();V0();v0();I();Y6=new kz({accounts:()=>v.list(),usage:async($)=>n1($)??{state:"network",reason:"额度缓存尚未就绪,后台刷新中"},cachedUsage:X9,identity:($)=>v.fingerprint($),pendingLogin:g2,now:Date.now,stateFile:dY,compatible:async($,Z,J)=>{let Q=G0("codex-sub",$);if(!Q)return"订阅来源 MISS";return xF(Q,Z,J)}})});import{createHash as wz,randomUUID as EF}from"node:crypto";function D4($,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 O$($){let Z=V$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function Y$($){return!V$.has($)}function A$($,Z,J){V$.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 y9($){return V$.get($)?.elementCount??0}function yz($){let Z=V$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function F4($,Z){return V$.get($)?.deadElements.has(Z)??!1}function vz($,Z){let J=V$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function V6($){let Z=O$($);return Z.sequence+=1,Z.sequence}function BJ($,Z){$.deadElements.add(Z)}function fz($){return wz("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function wF($,Z,J){let Q=[...$.contentFingerprints].filter(([Y])=>Y!==Z).map(([,Y])=>Y);if(J&&Z!==C.footer)Q.push(J);return wz("sha256").update(Q.sort().join(`
118
+ `)).digest("hex")}async function w9($,Z,J,Q){let Y=J?JSON.stringify({...J,..."sequence"in J?{uuid:EF()}:{}}):void 0,V=`cardkit ${$} ${Z}`;return p1(V,async()=>{let X=await y$(),H=AbortSignal.timeout(CF),z;try{return z=await X0(`${SF}${Z}`,{method:$,headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json"},...Y!==void 0?{body:Y}:{},signal:H}),(await z$(z,V))?.data}catch(G){if(H.aborted&&H.reason?.name==="TimeoutError")G=H.reason;if(z&&G instanceof y0)Object.assign(G,{httpStatus:z.status});throw Q?.(G),G}},{api:"cardkit"})}function _J($){return $ instanceof y0&&($.code===200770||$.code==="200770")}function hz($){if(_J($))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 I3($,{api:"cardkit"})}async function X6($,Z,J,Q){let Y=!1;try{await w9(Z,J,{...Q,sequence:V6($)},(V)=>{if(hz(V))Y=!0})}catch(V){if(!Y||!_J(V))throw V;B(`cardkit confirm ${Z} ${J}: ${V}; retrying same state with new UUID and sequence`),await w9(Z,J,{...Q,sequence:V6($)})}}async function Iz($,Z,J,Q){let Y=J.element_id,V=!1;try{await w9("POST",`/cards/${$}/elements`,{type:Q.type??"append",...Q.targetElementId?{target_element_id:Q.targetElementId}:{},elements:JSON.stringify([J]),sequence:V6($)},(X)=>{if(hz(X)){if(V=!0,Y)Z.uncertainAdds.add(Y)}})}catch(X){let H=X,z=Y&&Z.uncertainAdds.has(Y)&&KJ(H?.code,H);if(!Y||!(z||V&&_J(X)))throw X;B(`cardkit reconcile uncertain add ${$} element=${Y}: ${X}; confirming latest content with PUT`),await X6($,"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 yF($){return new Promise((Z)=>setTimeout(Z,$))}function vF($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function fF($){await X6($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}})})}async function H6($,Z,J,Q,Y=!1,V={}){let X=(H)=>{let z=typeof H==="object"&&H!==null?H:null,G={cardId:$,operation:Z,elementId:V.elementId,targetElementId:V.targetElementId,code:z?.code,httpStatus:z?.httpStatus,logId:z?.logId,message:H instanceof Error?H.message:String(H),apiMessage:z?.apiMessage};if(D4(G.code,G))G.capacityFingerprint=wF(O$($),V.elementId,V.contentFingerprint);try{if(!Y||Y==="non-capacity"&&D4(G.code,G))O$($).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(H){if(!vF(H)){B(`cardkit ${Z} ${$}: ${H}`),X(H);return}B(`cardkit ${Z} ${$}: streaming closed (code=${H.code}) — reopening`)}try{await fF($)}catch(H){B(`cardkit STREAMING_REOPEN_FAILED ${$}: ${H}`),X(H);return}try{await J()}catch(H){B(`cardkit ${Z} ${$} retry-after-reopen: ${H}`),X(H)}}function hF($){return typeof $==="object"&&$!==null&&$.code===200740}async function h$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:bF,Q=null;for(let Y=0;Y<J.length;Y++){let V=J[Y]??0;if(V>0)await yF(V);try{let X=await w9("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,!hF(X)||Y===J.length-1)throw X;let H=J[Y+1]??0;B(`cardkit id_convert ${$}: empty result, retry ${Y+2}/${J.length} in ${H}ms`)}}throw Q}async function T1($){let Z=V$.get($);if(!Z)return;await Z.queue}function N0($,Z,J={},Q,Y="all"){if(Y$($))return Promise.resolve();let V=O$($);if(V.closing)return Promise.resolve();let X=U1(Z),H=X.element_id,z=fz(X),G=()=>{if(!H)return;BJ(V,H),V.failedAdds.set(H,J)};return V.queue=V.queue.then(()=>H6($,"addElement",async()=>{if(await Iz($,V,X,J),H!==C.footer)V.contentFingerprints.set(H??`#${V.sequence}`,z);if(H)V.deadElements.delete(H),V.failedAdds.delete(H),V.failedReplacements.delete(H)},(W)=>{G(),Q?.(W.code,W)},Y==="capacity"?"non-capacity":!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:z})),V.queue}function P0($,Z,J,Q,Y=!0){if(Y$($))return Promise.resolve();let V=O$($);if(V.closing)return Promise.resolve();let X=U1(J),H=fz(X),z=()=>{BJ(V,Z),V.failedReplacements.add(Z)};return V.queue=V.queue.then(()=>H6($,`replaceElement ${Z}`,async()=>{let G=V.failedAdds.get(Z);if(V.deadElements.has(Z)&&!G&&!V.failedReplacements.has(Z))return;if(G)await Iz($,V,X,G);else await X6($,"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,H)},(G)=>{if(Y)z();Q?.(G.code,G)},!Y,{elementId:Z,contentFingerprint:H})),V.queue}async function K0($,Z,J,Q={}){if(Y$($))return!1;let Y=O$($);if(Y.closing)return!1;let V=!1;return await P0($,Z,J,(X,H)=>{if(V=!0,H)Q.onFailure?.(H)},Q.notifyCardFailure!==!1),!V&&!Y.deadElements.has(Z)}async function gz($,Z,J){if(Y$($))return{landed:!1};let Q=O$($);if(Q.closing)return{landed:!1};let Y;return await P0($,Z,J,(V,X)=>{Y=X}),{landed:!Y&&!Q.deadElements.has(Z),...Y?{failure:Y}:{}}}async function X2($,Z,J={}){let Q=await M4($,Z,J);if(Q.failure)J.onFailure?.(Q.failure);return Q.landed}async function M4($,Z,J={}){if(Y$($))return{landed:!1};let Q=O$($);if(Q.closing)return{landed:!1};let Y=Z.element_id,V;return await N0($,Z,J,(X,H)=>{V=H}),{landed:!V&&!(Y&&Q.deadElements.has(Y)),...V?{failure:V}:{}}}function IF($,Z,J){if(Y$($))return Promise.resolve();let Q=O$($);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(()=>H6($,`deleteElement ${Z}`,async()=>{if(Y())return;let V=V6($);await w9("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),BJ(Q,Z)},(V)=>J?.(V.code,V),!0,{elementId:Z})),Q.queue}async function mz($,Z,J){if(Y$($))return!1;let Q=O$($);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 IF($,Z,(V,X)=>{if(Y=!0,X)J?.(X)}),!Y&&Q.deadElements.has(Z)}function U4($,Z){if(Y$($)||V$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Q=V2.get($);if(!Q)Q={latest:J,lastSent:"",timer:null,inFlight:!1},V2.set($,Q);else{if(Q.latest===J)return;Q.latest=J}pz($,Q)}function pz($,Z){if(Z.timer||Z.inFlight||Z.latest===Z.lastSent)return;Z.timer=setTimeout(()=>{if(V2.get($)!==Z)return;if(Z.timer=null,Y$($)||V$.get($)?.closing){V2.delete($);return}if(Z.latest===Z.lastSent)return;let J=Z.latest;Z.inFlight=!0,C0($,{config:{summary:{content:J}}}).then((Q)=>{if(V2.get($)!==Z)return;if(Z.inFlight=!1,Q)Z.lastSent=J;if(Z.latest!==J&&!Y$($)&&!V$.get($)?.closing)pz($,Z)})},kF)}function i0($){let Z=V2.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;V2.delete($)}function z6($,Z){return C0($,Z).then(()=>{})}async function C0($,Z,J){if(Y$($))return!1;let Q=O$($);if(Q.closing)return!1;let Y=!1,V=!1;return Q.queue=Q.queue.then(()=>H6($,"patchSettings",async()=>{if(Y$($))return;await X6($,"PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z)}),Y=!0},(X)=>{V=!0,J?.(X)},!0)),await Q.queue,Y&&!V&&!Y$($)}async function B$($){let Z=V$.get($);if(!Z){i0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,i0($),await Z.queue,V$.delete($)}var SF="https://open.feishu.cn/open-apis/cardkit/v1",CF=15000,bF,V$,V2,kF=1500;var Z1=R(()=>{o0();e();b2();I();h0();bF=[0,250,750,1500];V$=new Map,V2=new Map});function I$($){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 cz($,Z){let J=Z.replace(/[&<>\\`*_\[\]~]/g,(z)=>`&#${z.charCodeAt(0)};`),Q=typeof $.used==="number"&&typeof $.total==="number"?` · ${$.used}/${$.total}`:"",Y=$.percent;if(Y===null||!Number.isFinite(Y)||Y<0||Y>100)return[{tag:"markdown",content:`**${J} · MISS${Q}**`}];let V=Math.round(Y/100*6),X=Y>=100?"red":Y>=80?"orange":"green",H=$.unreportedFull?"满窗 · 0.15 份":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?`${I$($.resetsAt)} 重置`:"重置时间 MISS";return[{tag:"markdown",content:`**${J} · ${Math.round(Y)}%${Q}**
119
119
  <font color='${X}'>${"▰".repeat(V)}${"▱".repeat(6-V)}</font>`},{tag:"markdown",content:`<font color='grey'>${H}</font>`,text_size:"notation"}]}var iz={};d$(iz,{codexAccountSummary:()=>v9,codexAccountPanel:()=>f9,codexAccountCard:()=>m$,CODEX_ACCOUNTS_PAGE_SIZE:()=>G6});function J1($){return $.replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function lz($){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 v9($){let[Z,J]=dz[$.phase],Q=$.name&&$.name.length>40?$.name.slice(0,37)+"…":$.name;return`${Z} Codex · ${Q?`${Q} · `:""}${$.title??J}`}function m$($,Z=!1){return{schema:"2.0",config:{update_multi:!0,width_mode:"compact",streaming_mode:Z,summary:{content:v9($)}},body:{elements:[f9($)]}}}function f9($){let[,,Z]=dz[$.phase],J=[];if($.flow==="login"&&["connecting","waiting","checking","success"].includes($.phase)){let Q=$.phase==="connecting"?0:$.phase==="waiting"?1:2;J.push(b0(["连接","授权","就绪"].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(lz([[g$("验证码"),{tag:"markdown",content:`**${$.verification.code}**`,text_size:"heading-2"}],[b0(`[**打开授权页 ↗**](${Q.href.replace(/\(/g,"%28").replace(/\)/g,"%29")})`),g$("登录账号,输入左侧验证码")]]))}if($.current)J.push(lz([[g$("当前使用"),b0(`**${J1($.current)}**`)],...$.selected&&$.selected!==$.current?[[g$("下次启动"),b0(`**${J1($.selected)}**`)]]:[]]));if($.plan||$.email)J.push(b0([$.plan?.toUpperCase(),$.email].filter(Boolean).map((Q)=>J1(Q)).join(" · ")));if($.message)J.push(b0(J1($.message)));if($.resetUsage){let Q=$.resetUsage;if(J.push(b0(`**重置卡** ${Q.state==="ok"&&Q.resetCredits!=null?`${Q.resetCredits} 次可用`:"MISS"}`)),Q.state==="ok"){for(let[Y,V]of[[Q.fiveHour,"5h"],[Q.weekly,"周"]])if(Y)J.push(...cz(Y,V))}else J.push(b0("⚠️ 额度 MISS · 查看详情中的查询错误"))}if($.total)J.push(...gF($));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:[b0(["`hi` · 打开控制台;未运行时启动","`hi 备注` · 本次指定账号;换号时重启并续跑","`codex-login [备注]` · 设备码登录;省略备注为默认账号","`codex-login-cancel [备注]` · 取消本人在本群的登录;仅一个任务时可省略备注","`codex-accounts [页码]` · 查看账号、额度与调度顺序","`codex-reset [备注]` · 使用一次重置卡;省略备注为当前使用账号","`codex-account` · 查看当前账号与下次启动策略","`codex-account 备注` · 持久指定账号,下次启动生效","`codex-auto` · 清除指定,下次启动自动选择","`codex-account-delete 备注` · 删除额外账号"].join(`
120
- `)),g$("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(g$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[b0(J1($.details))]});return{tag:"collapsible_panel",element_id:C.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:v9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:$.phase==="accounts"?"8px":"12px",...$.phase==="accounts"?{vertical_spacing:"8px"}:{},elements:J}}function uz($,Z){let J=$?.percent;if(J==null||!Number.isFinite(J)||J<0||J>100)return b0(`${Z} MISS`);let Q=Math.round(J/100*6),Y=J>=100?"red":J>=80?"orange":"green",V=$.unreportedFull?"满窗":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?I$($.resetsAt):"MISS";return b0(`${Z} <font color='${Y}'>${"▰".repeat(Q)}${"▱".repeat(6-Q)}</font> ${Math.round(J)}% <font color='grey'>「${V}」</font>`)}function gF($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/G6)),Q=$.page??1;if(!Number.isInteger(Q)||Q<1||Q>J)throw Error(`页码应为 1–${J}`);let Y=[],V=$.scheduling?.candidates.filter((z)=>z.state==="ready").sort(J8)??[],X=new Map(V.map((z,G)=>[z.account.id,G+1])),H=Z.entries.slice().sort((z,G)=>(X.get(z.account.id)??1/0)-(X.get(G.account.id)??1/0));for(let z of H.slice((Q-1)*G6,Q*G6)){let G=z.usage,W=[],K=$.scheduling?.candidates.find((L)=>L.account.id===z.account.id),_=X.get(z.account.id),j=z.duplicateOf?"重复":K?.state==="ready"?K.priority==="expiring"?"临期优先":`${K.score.toPrecision(3)}/h`:"MISS";if(Y.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`#${_??"—"}·${z.account.name}「${j}」`},background_color:"grey-50"},border:{color:"grey-100",corner_radius:"8px"},padding:"8px",vertical_spacing:"2px",elements:W}),W.push(g$(`邮箱:${z.email??"MISS"}`)),z.emailError)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"邮箱查询错误"}},elements:[b0(J1(z.emailError))]});if(z.duplicateOf){W.push(g$(`与「${z.duplicateOf}」同一账号,合计只计一次`));continue}if(K&&K.state!=="ready"){if(W.push(g$(K.state==="exhausted"?"⏳ 耗尽 · 暂不参与":K.state==="excluded"?"Ultra 自动排除 Plus":K.state==="waiting"?`⏳ 周余量 ${K.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),K.state==="miss"&&K.reason&&G.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[b0(J1(K.reason))]})}if(G.state!=="ok"){if(W.push(b0(G.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),G.state==="network"&&G.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[b0(J1(G.reason))]});continue}if(W.push(uz(G.weekly,"周")),G.fiveHour)W.push(uz(G.fiveHour,"5h"))}if(J>1)Y.push(g$(`${Q}/${J} 页 · ${Q<J?`下一页 codex-accounts ${Q+1}`:"首页 codex-accounts"}`));return Y}var G6=4,dz,b0=($)=>({tag:"markdown",content:$}),g$=($)=>({tag:"markdown",content:`<font color='grey'>${J1($)}</font>`,text_size:"notation"});var O4=R(()=>{h0();dz={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 A4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=mF){let Q,Y=await J.sendCard($,m$(Z,!0),(X)=>{Q=X});if(!Y)throw Error(`Codex 账号卡片发送失败:${k(Q)}`);let V=await J.convertMessageToCard(Y);return J.recordCardCreated(V,1),new A4(V,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=f9($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=f9($);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:(H)=>{Q=H}}),X=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:v9($)}}},(H)=>{Y=H});if(!V||!X)throw Error(`Codex 账号卡片更新失败:内容 ${V?"OK":k(Q)},状态 ${X?"OK":k(Y)}`);if(J)await this.deps.dispose(this.cardId)}}var mF;var nz=R(()=>{e();Z1();h0();O4();mF={sendCard:i,convertMessageToCard:h$,recordCardCreated:A$,replaceElementChecked:K0,patchSettingsChecked:C0,dispose:B$}});var qJ={};d$(qJ,{settleCodexAccountCards:()=>jJ,runCodexNamedHi:()=>cF,runCodexAccountCommand:()=>lF});import{createHash as pF}from"node:crypto";function h9($,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 az($,Z){let J;if(!await i($.chatId,m$(h9(Z)),(Q)=>{J=Q}))throw Error(`Codex 错误卡片发送失败
121
- ${k(J)}`)}async function cF($,Z){let J=await A4.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(h9(Q,Z))}}async function jJ(){let Z=(await Promise.allSettled([...z2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function lF($,Z,J,Q,Y){if(Z==="reset"){await dF($,J,Y);return}let V={chatId:$.chatId,userOpenId:Q};if(Z==="login-cancel"){try{let G=$2.pending(V);if(!J&&G.length!==1)throw Error(G.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?v.find(J).id:G[0];await $2.cancel(W,V),await z2.get(W)}catch(G){await az($,G)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,H=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),z=await A4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号邮箱与额度…":H?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let j=v.find(J);if(z2.has(j.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:L}=v.remove(j.id);ZH(E0("codex-sub"),j.id),L1(j.id),await z.finish({phase:"deleted",name:j.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:L?`已清除 ${L} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let j=J?Number(J):1,L=$.codexAccountId(),q=G0("codex-sub",L),D=()=>$.currentProvider()==="codex"?$.currentModelLabel():q?.defaultModel,F=D(),U;if(!F)try{if(!q)throw Error("Codex 订阅来源尚未初始化");if(F=D(),!F)throw Error(q.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(T){U=`${v.get(L).name}:${T instanceof Error?T.message:String(T)}`}let M=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,O=F?await Y6.choose({model:F,effort:M}):null,A=O?zJ(O.candidates.flatMap((T)=>{let S=(T.usage?.state==="network"||T.usage?.state==="rate_limited"?X9(T.account.id):null)??T.usage;return S?[{account:T.account,usage:S,fingerprint:T.identity.startsWith("record:")?null:T.identity}]:[]})):await Q6();if(U)B(`codex-accounts: scheduling MISS: ${U}`);await z.finish({phase:"accounts",total:await bz(A),currentId:L,...v.preferred($.sessionName)?{selectedId:v.selected($.sessionName)}:{},page:j,...O?{scheduling:{candidates:O.candidates,ultra:M==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:U,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");v.selectAuto($.sessionName),await z.finish({phase:"selected",name:"自动选择",current:v.get($.codexAccountId()).name,selected:"自动 · 未使用 / 临期 / 评分",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await z.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 j=v.find(J),L=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,D=v.get($.codexAccountId()).name;if($.currentProvider()==="codex")R1($.sessionName,"codex",L,q,"codex-sub");if(v.select($.sessionName,j.id),$.currentProvider()==="codex")$.selectedModel=L,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await z.finish({phase:"selected",name:j.name,current:D,selected:j.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Q)throw Error("无法确认登录发起者");if(H)await lH(),await z.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let G=v.ensure(J);if(s3(G.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(z2.has(G.id))throw Error("登录结果正在更新,请稍等");let W=await $2.start(G.id,V);try{await z.update({phase:"waiting",flow:"login",name:G.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${G.name}`:""}`})}catch(j){throw await $2.cancel(G.id,V),j}let K=(async()=>{let j;try{j=await W.done}catch(L){await z.finish(h9(L,G.name));return}k9(),G0("codex-sub",G.id),await z.finish({phase:"success",flow:"login",name:G.name,email:j.email,plan:j.planType,hint:`目录与额度正在后台刷新 · 优先使用:codex-account ${G.id==="default"?"default":G.name}`})})();z2.set(G.id,K);let _=()=>{if(z2.get(G.id)===K)z2.delete(G.id)};K.then(_,(j)=>{B(`codex-login: terminal card write failed: ${j}`),_()})}catch(G){B(`codex-${Z}: ${G}`),await z.finish(h9(G,X))}}async function dF($,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(G$($.proc))}catch(G){B(`codex-reset: ${G}`),await az($,G);return}let Y=await A4.open($.chatId,{phase:"checking",name:Q.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let G=pF("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await FX(Q.id,G)}catch(G){B(`codex-reset: ${G}`),await Y.finish(h9(G,Q.name));return}let X=uF[V.outcome],z=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
122
- `);await Y.finish({...X,name:Q.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var z2,uF;var W6=R(()=>{e();D0();pZ();Q0();J6();A8();GJ();WJ();nz();O4();I();U$();z2=new Map;uF={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as iF}from"node:fs";function nF($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function aF($,Z){let J=[`[token_source.${$}]`],Q=(Y,V)=>{if(V!==void 0)J.push(`${Y} = "${nF(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(`
120
+ `)),g$("备注可用 default 指定设备默认账号;默认账号不可删除。")]});if($.hint)J.push(g$($.hint));if($.details)J.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查看详情"}},elements:[b0(J1($.details))]});return{tag:"collapsible_panel",element_id:C.codexAccountPanel,expanded:!0,header:{title:{tag:"plain_text",content:v9($)},background_color:`${Z}-50`},border:{color:`${Z}-100`,corner_radius:"8px"},padding:$.phase==="accounts"?"8px":"12px",...$.phase==="accounts"?{vertical_spacing:"8px"}:{},elements:J}}function uz($,Z){let J=$?.percent;if(J==null||!Number.isFinite(J)||J<0||J>100)return b0(`${Z} MISS`);let Q=Math.round(J/100*6),Y=J>=100?"red":J>=80?"orange":"green",V=$.unreportedFull?"满窗":$.resetsAt&&Number.isFinite($.resetsAt.getTime())?I$($.resetsAt):"MISS";return b0(`${Z} <font color='${Y}'>${"▰".repeat(Q)}${"▱".repeat(6-Q)}</font> ${Math.round(J)}% <font color='grey'>「${V}」</font>`)}function gF($){let Z=$.total,J=Math.max(1,Math.ceil(Z.entries.length/G6)),Q=$.page??1;if(!Number.isInteger(Q)||Q<1||Q>J)throw Error(`页码应为 1–${J}`);let Y=[],V=$.scheduling?.candidates.filter((z)=>z.state==="ready").sort(J8)??[],X=new Map(V.map((z,G)=>[z.account.id,G+1])),H=Z.entries.slice().sort((z,G)=>(X.get(z.account.id)??1/0)-(X.get(G.account.id)??1/0));for(let z of H.slice((Q-1)*G6,Q*G6)){let G=z.usage,W=[],K=$.scheduling?.candidates.find((L)=>L.account.id===z.account.id),_=X.get(z.account.id),j=z.duplicateOf?"重复":K?.state==="ready"?K.priority==="expiring"?"临期优先":`${K.score.toPrecision(3)}/h`:"MISS";if(Y.push({tag:"collapsible_panel",expanded:!0,header:{title:{tag:"plain_text",content:`#${_??"—"}·${z.account.name}「${j}」 · 重置 ${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(g$(`邮箱:${z.email??"MISS"}`)),z.emailError)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"邮箱查询错误"}},elements:[b0(J1(z.emailError))]});if(z.duplicateOf){W.push(g$(`与「${z.duplicateOf}」同一账号,合计只计一次`));continue}if(K&&K.state!=="ready"){if(W.push(g$(K.state==="exhausted"?"⏳ 耗尽 · 暂不参与":K.state==="excluded"?"Ultra 自动排除 Plus":K.state==="waiting"?`⏳ 周余量 ${K.remaining?.toPrecision(3)} 份 · 未达 0.5 份`:"MISS · 无法排序")),K.state==="miss"&&K.reason&&G.state==="ok")W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"未参与原因"}},elements:[b0(J1(K.reason))]})}if(G.state!=="ok"){if(W.push(b0(G.state==="no_credentials"?"⚪ 未登录":"⚠️ 额度 MISS")),G.state==="network"&&G.reason)W.push({tag:"collapsible_panel",expanded:!1,header:{title:{tag:"plain_text",content:"查询错误"}},elements:[b0(J1(G.reason))]});continue}if(W.push(uz(G.weekly,"周")),G.fiveHour)W.push(uz(G.fiveHour,"5h"))}if(J>1)Y.push(g$(`${Q}/${J} 页 · ${Q<J?`下一页 codex-accounts ${Q+1}`:"首页 codex-accounts"}`));return Y}var G6=4,dz,b0=($)=>({tag:"markdown",content:$}),g$=($)=>({tag:"markdown",content:`<font color='grey'>${J1($)}</font>`,text_size:"notation"});var O4=R(()=>{h0();dz={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 A4{cardId;deps;tail=Promise.resolve();terminal=null;constructor($,Z){this.cardId=$;this.deps=Z}static async open($,Z,J=mF){let Q,Y=await J.sendCard($,m$(Z,!0),(X)=>{Q=X});if(!Y)throw Error(`Codex 账号卡片发送失败:${k(Q)}`);let V=await J.convertMessageToCard(Y);return J.recordCardCreated(V,1),new A4(V,J)}update($){if(this.terminal)return Promise.reject(Error("Codex 账号卡片已结束"));let Z=f9($);return this.enqueue(()=>this.write($,Z,!1))}finish($){if(this.terminal)return this.terminal;let Z=f9($);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:(H)=>{Q=H}}),X=await this.deps.patchSettingsChecked(this.cardId,{config:{streaming_mode:!J,summary:{content:v9($)}}},(H)=>{Y=H});if(!V||!X)throw Error(`Codex 账号卡片更新失败:内容 ${V?"OK":k(Q)},状态 ${X?"OK":k(Y)}`);if(J)await this.deps.dispose(this.cardId)}}var mF;var nz=R(()=>{e();Z1();h0();O4();mF={sendCard:i,convertMessageToCard:h$,recordCardCreated:A$,replaceElementChecked:K0,patchSettingsChecked:C0,dispose:B$}});var qJ={};d$(qJ,{settleCodexAccountCards:()=>jJ,runCodexNamedHi:()=>cF,runCodexAccountCommand:()=>lF});import{createHash as pF}from"node:crypto";function h9($,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 az($,Z){let J;if(!await i($.chatId,m$(h9(Z)),(Q)=>{J=Q}))throw Error(`Codex 错误卡片发送失败
121
+ ${k(J)}`)}async function cF($,Z){let J=await A4.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(h9(Q,Z))}}async function jJ(){let Z=(await Promise.allSettled([...z2.values()])).filter((J)=>J.status==="rejected").map((J)=>J.reason);if(Z.length)throw AggregateError(Z,"Codex 账号卡片未全部写入")}async function lF($,Z,J,Q,Y){if(Z==="reset"){await dF($,J,Y);return}let V={chatId:$.chatId,userOpenId:Q};if(Z==="login-cancel"){try{let G=$2.pending(V);if(!J&&G.length!==1)throw Error(G.length?"有多个登录任务;请指定 codex-login-cancel 备注":"本群没有你的登录任务");let W=J?v.find(J).id:G[0];await $2.cancel(W,V),await z2.get(W)}catch(G){await az($,G)}return}let X=Z==="login"?J||"默认":Z==="account"||Z==="account-delete"?J||void 0:void 0,H=Z==="login"&&!!J.trim()&&!["default","默认"].includes(J.normalize("NFC").trim().toLowerCase()),z=await A4.open($.chatId,{phase:Z==="login"?"connecting":"checking",name:X,...Z==="login"?{flow:"login"}:{},message:Z==="accounts"?"正在读取各账号邮箱与额度…":H?"正在检查默认账号登录状态…":Z==="login"?"正在获取设备码…":"正在核对账号…"});try{if(Z==="account-delete"){if(!J)throw Error("请指定要删除的账号;使用 codex-account-delete 备注");let j=v.find(J);if(z2.has(j.id))throw Error("账号登录或结果更新尚未结束;请先完成或取消登录后重试");let{clearedSelections:L}=v.remove(j.id);ZH(E0("codex-sub"),j.id),L1(j.id),await z.finish({phase:"deleted",name:j.name,message:"已删除本地账号记录与独立凭据,共享会话历史保留。",hint:L?`已清除 ${L} 个群的指定,下次启动自动选号 · codex-accounts 查看`:"codex-accounts 查看剩余账号"});return}if(Z==="accounts"){if(J&&!/^[1-9]\d*$/.test(J))throw Error("页码无效;使用 codex-accounts [页码]");let j=J?Number(J):1,L=$.codexAccountId(),q=G0("codex-sub",L),D=()=>$.currentProvider()==="codex"?$.currentModelLabel():q?.defaultModel,F=D(),M;if(!F)try{if(!q)throw Error("Codex 订阅来源尚未初始化");if(F=D(),!F)throw Error(q.modelCatalogState?.error??"Codex 模型目录未提供可用的默认模型")}catch(T){M=`${v.get(L).name}:${T instanceof Error?T.message:String(T)}`}let U=$.currentProvider()==="codex"?$.currentEffortLabel()??void 0:void 0,O=F?await Y6.choose({model:F,effort:U}):null,A=O?zJ(O.candidates.flatMap((T)=>{let S=(T.usage?.state==="network"||T.usage?.state==="rate_limited"?X9(T.account.id):null)??T.usage;return S?[{account:T.account,usage:S,fingerprint:T.identity.startsWith("record:")?null:T.identity}]:[]})):await Q6();if(M)B(`codex-accounts: scheduling MISS: ${M}`);await z.finish({phase:"accounts",total:await bz(A),currentId:L,...v.preferred($.sessionName)?{selectedId:v.selected($.sessionName)}:{},page:j,...O?{scheduling:{candidates:O.candidates,ultra:U==="ultra"}}:{message:"⚠️ 调度顺序 MISS:尚未确定 Codex 模型",details:M,hint:"可用 hi 备注指定已登录账号,或通过 md 检查模型目录"}});return}if(Z==="auto"){if(J)throw Error("codex-auto 不需要备注");v.selectAuto($.sessionName),await z.finish({phase:"selected",name:"自动选择",current:v.get($.codexAccountId()).name,selected:"自动 · 未使用 / 临期 / 评分",hint:"Ultra:Pro 且周余量 ≥ 0.5 份"});return}if(Z==="account"){if(!J){await z.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 j=v.find(J),L=$.currentProvider()==="codex"?$.currentModelLabel():null,q=$.currentProvider()==="codex"?$.currentEffortLabel():null,D=v.get($.codexAccountId()).name;if($.currentProvider()==="codex")R1($.sessionName,"codex",L,q,"codex-sub");if(v.select($.sessionName,j.id),$.currentProvider()==="codex")$.selectedModel=L,$.selectedEffort=q,$.selectedTokenSourceId="codex-sub";await z.finish({phase:"selected",name:j.name,current:D,selected:j.name,hint:"restart 直接使用 · 不检查调度门槛"});return}if(Z!=="login")throw Error("未知 Codex 账号命令");if(!Q)throw Error("无法确认登录发起者");if(H)await lH(),await z.update({phase:"connecting",flow:"login",name:X,message:"正在获取设备码…"});let G=v.ensure(J);if(s3(G.id))throw Error("账号正在使用中;重新登录前先 kill 使用该账号的会话,或用新备注添加账号");if(z2.has(G.id))throw Error("登录结果正在更新,请稍等");let W=await $2.start(G.id,V);try{await z.update({phase:"waiting",flow:"login",name:G.name,verification:{url:W.verificationUrl,code:W.userCode},hint:`取消:codex-login-cancel${J?` ${G.name}`:""}`})}catch(j){throw await $2.cancel(G.id,V),j}let K=(async()=>{let j;try{j=await W.done}catch(L){await z.finish(h9(L,G.name));return}k9(),G0("codex-sub",G.id),await z.finish({phase:"success",flow:"login",name:G.name,email:j.email,plan:j.planType,hint:`目录与额度正在后台刷新 · 优先使用:codex-account ${G.id==="default"?"default":G.name}`})})();z2.set(G.id,K);let _=()=>{if(z2.get(G.id)===K)z2.delete(G.id)};K.then(_,(j)=>{B(`codex-login: terminal card write failed: ${j}`),_()})}catch(G){B(`codex-${Z}: ${G}`),await z.finish(h9(G,X))}}async function dF($,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(G$($.proc))}catch(G){B(`codex-reset: ${G}`),await az($,G);return}let Y=await A4.open($.chatId,{phase:"checking",name:Q.name,title:"正在使用重置卡",message:"正在提交重置请求…"}),V;try{let G=pF("sha256").update(JSON.stringify(["lodestar-codex-reset",$.chatId,J])).digest("hex");V=await FX(Q.id,G)}catch(G){B(`codex-reset: ${G}`),await Y.finish(h9(G,Q.name));return}let X=uF[V.outcome],z=[V.usage.state==="ok"?void 0:`额度刷新失败:${V.usage.state==="network"?V.usage.reason??"MISS":V.usage.state}`,V.cleanupError].filter(Boolean).join(`
122
+ `);await Y.finish({...X,name:Q.name,resetUsage:V.usage,...z?{phase:"warning",details:z}:{},hint:"codex-accounts 查看各账号额度"})}var z2,uF;var W6=R(()=>{e();D0();pZ();Q0();J6();A8();GJ();WJ();nz();O4();I();M$();z2=new Map;uF={reset:{phase:"success",title:"额度已重置",message:"已使用 1 次重置卡。"},alreadyRedeemed:{phase:"success",title:"本次重置已完成",message:"本次请求此前已处理,没有重复使用重置卡。"},nothingToReset:{phase:"current",title:"无需重置",message:"当前没有符合条件的额度窗口,未使用重置卡。"},noCredit:{phase:"warning",title:"没有可用重置卡",message:"该账号没有可用的重置卡,额度未重置。"}}});import{readFileSync as iF}from"node:fs";function nF($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}function aF($,Z){let J=[`[token_source.${$}]`],Q=(Y,V)=>{if(V!==void 0)J.push(`${Y} = "${nF(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(`
123
123
  `)}function oF($,Z){sF({[$]:Z})}function sF($){if(!Object.keys($).length)return;let Z=iF(w0,"utf8"),J=t4().token_sources,Q={};for(let[z,G]of Object.entries($)){let W=nZ(J,z,G);J={...J,...W},Object.assign(Q,W)}E9(J);let Y=new Set(Object.keys(Q).map((z)=>`[token_source.${z}]`)),V=Z.split(`
124
124
  `),X=!1,H=[];for(let z of V){let G=z.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(G)X=Y.has(G);if(!X)H.push(z)}while(H.length&&H[H.length-1]==="")H.pop();s0(w0,H.join(`
125
125
  `)+`
@@ -131,80 +131,80 @@ ${k(J)}`)}async function cF($,Z){let J=await A4.open($.chatId,{phase:"checking",
131
131
  `))}async function rF($,Z){let J=E0(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=a1().find((Y)=>Y.setup?.commandSuffix===Z||Y.configSectionId===Z);if(Q?.setup){let Y=J.modelCatalogState?.status==="failed"?`${J.display} 当前不可用:${p0(J.modelCatalogState.error??"MISS")}
132
132
  `:"";await b($.chatId,Y+Q.setup.hint(J.display))}else if(J.kind==="codex-subscription"){if(!await i($.chatId,m$({phase:"current",title:"添加账号",message:"通过设备码完成浏览器授权",hint:"默认:codex-login · 额外:codex-login 备注"})))throw Error("Codex 登录引导卡片发送失败")}else if(J.kind==="claude-subscription")await b($.chatId,p.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 eF($,Z,J){let Q=a1().find((z)=>z.setup?.commandSuffix===Z||z.usageSetup?.commandSuffix===Z),Y=Q?.usageSetup?.commandSuffix===Z,V=Y?Q?.usageSetup:Q?.setup;if(!Q||!V||!Q.configSectionId){await b($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let X=V.parseArgs(J);if("error"in X){await b($.chatId,X.error);return}await b($.chatId,"正在后台校验账号配置,完成后会返回结果;其他操作可继续使用。");let H=!1;try{await tz(Q,X.config,V),H=!0;let z=E0(Q.configSectionId),G=tH(Q.configSectionId).map((_)=>E0(_)),W=G.find((_)=>(!Y||_?.enabled)&&_?.modelCatalogState?.status!=="ready");if(Y){let _=W?`
133
133
  模型目录仍为 MISS:${p0(W.modelCatalogState?.error??"尚未就绪",[X.config.management_token])}`:"";await b($.chatId,`✅ ${z?.display??Z} 真实余额校验通过,配置已保存。发送 hi 查看;回复页脚使用同一账户余额。${_}`);return}if(W?.modelCatalogState?.status==="failed"||G.some((_)=>!_)){let _=p0(W?.modelCatalogState?.error??"模型目录尚未就绪",[X.config.api_key,X.config.auth_token]);await b($.chatId,`❌ ${z?.display??Z} 凭据校验通过、配置已保存,但暂不可用:${_}
134
- 处理后等待后台刷新,发送 md 查看状态。`);return}let K=[...new Set(G.filter((_)=>!!_).map((_)=>c0(_.agent)))];await b($.chatId,`✅ ${z.display} 校验通过,配置已保存。${K.length>1?`${K.join(" 和 ")} 共用该账号。`:""}目录与额度在后台刷新;发送 md 查看模型。`)}catch(z){let G=H||z instanceof K6&&z.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",W=p0(z,[X.config.api_key,X.config.auth_token,X.config.management_token]);await b($.chatId,`❌ ${G}:${W}`)}}var _6=R(()=>{e();Q0();LJ();O4();f0();I();S9();B0()});function ZG($,Z){let J=Z.catch(async(Q)=>{let Y=`账号操作或结果呈现失败:${x(Q)}`;throw B(Y),await g($.chatId,`❌ ${Y}`),Q});PJ.add(J),J.finally(()=>PJ.delete(J)).catch((Q)=>B(`账号操作结果发送失败:${x(Q)}`))}function JG(){return[...PJ]}async function QG($,Z,J="",Q){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (W6(),qJ));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(() => (W6(),qJ)),_=V[1].toLowerCase(),j=K($,_,(V[2]??"").trim(),J,Q);if(_==="login"||_==="reset")ZG($,j);else await j;return!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (_6(),B6));return await K($,(X[1]??"").trim().toLowerCase()),!0}let H=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(H)return await $.runWorktreeCommand((H[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;let z=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(z)return await $.runFileDeliveryCommand((z[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let G=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(G){let{runTokenSourceSetup:K}=await Promise.resolve().then(() => (_6(),B6));return ZG($,K($,G[1].trim().toLowerCase(),(G[2]??"").trim())),!0}let W=$U.get(Z.trim().toLowerCase());if(!W)return!1;switch(W){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let K=!$.isRunning(),_=$.backendLabel(),j=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${_}`)):null,L=$.withModel(`\uD83D\uDE80 启动 ${_}`);if(!(K?await $.start({announce:!j,onStatus:(D)=>{L=D,$.setStatusCard(j,D)}}):!0))return await $.closeStatusCard(j,L.startsWith("❌")?L:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(j)await $.closeStatusCard(j,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:F}=await Promise.resolve().then(() => (O4(),iz)),U;if(!await i($.chatId,F({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"}),(M)=>{U=M}))throw Error(`额度等待卡片发送失败
135
- ${k(U)}`)}return!0}if(j)return await $.replaceStatusCardWithConsole(j,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(j,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let j=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!j,onStatus:(L)=>$.setStatusCard(j,L)}),await $.closeStatusCard(j,"\uD83D\uDED1 已取消额度恢复")}catch(L){throw await $.closeStatusCard(j,`❌ ${x(L)}`),L}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 j=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(j)await $.closeStatusCard(j,"⚪ 无正在执行的 turn");else await b($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let _=new Set;for(let[j,L]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(L)g0(j,L);Q$(j,"CrossMark"),_.add(j)}for(let j of $.pendingMidTurnMsgs)if(j.msgId&&!_.has(j.msgId))Q$(j.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0}case"kill":{let K=$.isRunning(),_=$.backendLabel($.proc?.provider??$.currentProvider()),j=K?`\uD83D\uDED1 停止 ${_}`:"⚪ session 当前未运行",L=await $.openStatusCard("kill",j,K?"red":"grey"),q=null,D=K?`✅ ${_} 已终止`:`⚪ ${_} 未运行`;try{await $.stop("已终止",{announce:!L,onStatus:(F)=>{$.setStatusCard(L,F)}})}catch(F){q=F,D=$.isRunning()?`❌ ${_} 未确认终止: ${x(F)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${_} 停止收尾失败: ${x(F)}`}finally{try{await $.closeStatusCard(L,D)}catch(F){B(`session "${$.sessionName}": kill status card close failed: ${x(F)}`),await g($.chatId,`${D}
136
- ⚠️ kill 状态卡片终态写入失败: ${x(F)}`)}}if(q&&!L)await g($.chatId,D)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?x0($.lastSessionId):"",_=$.backendLabel($.proc?.provider??$.currentProvider()),j=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${_}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${_}`),L=await $.openStatusCard("restart",j),q=j,D=await $.restart(!0,{announce:!L,onStatus:(U)=>{q=U,$.setStatusCard(L,U)}}),F=D?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(L,D?$.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"),_="\uD83E\uDDF9 清空并启动新会话",j=await $.restart(!1,{announce:!K,onStatus:(L)=>{_=L,$.setStatusCard(K,L)}});await $.closeStatusCard(K,j?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):_.startsWith("❌")?_:"❌ 清空失败")}return!0}}var $U,PJ;var DJ=R(()=>{e();I();$U=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"]]),PJ=new Set});function R0($,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 G2($){switch($){case"delegated":return"委派任务";case"subagent":return"子 Agent";case"background":return"后台进程"}}function VG($){switch($){case"delegated":return"\uD83E\uDDE0";case"subagent":return"\uD83E\uDD16";case"background":return"⚙️"}}var YG;var FJ=R(()=>{YG=["delegated","subagent","background"]});function m9($,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)}…
134
+ 处理后等待后台刷新,发送 md 查看状态。`);return}let K=[...new Set(G.filter((_)=>!!_).map((_)=>c0(_.agent)))];await b($.chatId,`✅ ${z.display} 校验通过,配置已保存。${K.length>1?`${K.join(" 和 ")} 共用该账号。`:""}目录与额度在后台刷新;发送 md 查看模型。`)}catch(z){let G=H||z instanceof K6&&z.saved?"配置已保存,但后续处理失败":"配置失败,未保存,原配置保持不变",W=p0(z,[X.config.api_key,X.config.auth_token,X.config.management_token]);await b($.chatId,`❌ ${G}:${W}`)}}var _6=R(()=>{e();Q0();LJ();O4();f0();I();S9();B0()});function ZG($,Z){let J=Z.catch(async(Q)=>{let Y=`账号操作或结果呈现失败:${x(Q)}`;throw B(Y),await g($.chatId,`❌ ${Y}`),Q});PJ.add(J),J.finally(()=>PJ.delete(J)).catch((Q)=>B(`账号操作结果发送失败:${x(Q)}`))}function JG(){return[...PJ]}async function QG($,Z,J="",Q){let Y=Z.trim().match(/^hi[ \t]+([^\r\n]+)$/i);if(Y){let{runCodexNamedHi:K}=await Promise.resolve().then(() => (W6(),qJ));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(() => (W6(),qJ)),_=V[1].toLowerCase(),j=K($,_,(V[2]??"").trim(),J,Q);if(_==="login"||_==="reset")ZG($,j);else await j;return!0}let X=Z.trim().match(/^claude-sub(?:[ \t]+([^\r\n]+))?$/i);if(X){let{runClaudeSubscriptionCommand:K}=await Promise.resolve().then(() => (_6(),B6));return await K($,(X[1]??"").trim().toLowerCase()),!0}let H=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(H)return await $.runWorktreeCommand((H[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;let z=Z.trim().match(/^files(?:[ \t]+([^\r\n]+))?$/i);if(z)return await $.runFileDeliveryCommand((z[1]??"").trim(),J),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let G=Z.trim().match(/^([\w-]+)-setup(?:\s+([\s\S]+))?$/i);if(G){let{runTokenSourceSetup:K}=await Promise.resolve().then(() => (_6(),B6));return ZG($,K($,G[1].trim().toLowerCase(),(G[2]??"").trim())),!0}let W=$M.get(Z.trim().toLowerCase());if(!W)return!1;switch(W){case"model":return await $.showModelPanel(),!0;case"compact":return await $.runCompactCommand(),!0;case"hi":{let K=!$.isRunning(),_=$.backendLabel(),j=K?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${_}`)):null,L=$.withModel(`\uD83D\uDE80 启动 ${_}`);if(!(K?await $.start({announce:!j,onStatus:(D)=>{L=D,$.setStatusCard(j,D)}}):!0))return await $.closeStatusCard(j,L.startsWith("❌")?L:"❌ 启动失败"),!0;if($.proc?.turnRetry?.reason==="quota"){if(j)await $.closeStatusCard(j,"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消");else{let{codexAccountCard:F}=await Promise.resolve().then(() => (O4(),iz)),M;if(!await i($.chatId,F({phase:"checking",title:"等待额度",message:"⏳ 等待额度恢复 · 可用后自动启动,stop 可取消"}),(U)=>{M=U}))throw Error(`额度等待卡片发送失败
135
+ ${k(M)}`)}return!0}if(j)return await $.replaceStatusCardWithConsole(j,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(K)await $.closeStatusCard(j,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":{let K=$.cancelFileDeliveries("用户停止了任务");if(await $.cancelAgentRuns("stop command"),$.proc?.turnRetry?.reason==="quota"){let j=await $.openStatusCard("stop","\uD83D\uDED1 停止额度等待");try{await $.stop("已取消额度恢复",{announce:!j,onStatus:(L)=>$.setStatusCard(j,L)}),await $.closeStatusCard(j,"\uD83D\uDED1 已取消额度恢复")}catch(L){throw await $.closeStatusCard(j,`❌ ${x(L)}`),L}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 j=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(j)await $.closeStatusCard(j,"⚪ 无正在执行的 turn");else await b($.chatId,"⚪ 当前没有正在执行的 turn");return!0}B(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let _=new Set;for(let[j,L]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(L)g0(j,L);Q$(j,"CrossMark"),_.add(j)}for(let j of $.pendingMidTurnMsgs)if(j.msgId&&!_.has(j.msgId))Q$(j.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0}case"kill":{let K=$.isRunning(),_=$.backendLabel($.proc?.provider??$.currentProvider()),j=K?`\uD83D\uDED1 停止 ${_}`:"⚪ session 当前未运行",L=await $.openStatusCard("kill",j,K?"red":"grey"),q=null,D=K?`✅ ${_} 已终止`:`⚪ ${_} 未运行`;try{await $.stop("已终止",{announce:!L,onStatus:(F)=>{$.setStatusCard(L,F)}})}catch(F){q=F,D=$.isRunning()?`❌ ${_} 未确认终止: ${x(F)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${_} 停止收尾失败: ${x(F)}`}finally{try{await $.closeStatusCard(L,D)}catch(F){B(`session "${$.sessionName}": kill status card close failed: ${x(F)}`),await g($.chatId,`${D}
136
+ ⚠️ kill 状态卡片终态写入失败: ${x(F)}`)}}if(q&&!L)await g($.chatId,D)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let K=$.lastSessionId?x0($.lastSessionId):"",_=$.backendLabel($.proc?.provider??$.currentProvider()),j=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${_}`):K?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`):$.withModel(`\uD83D\uDD01 启动 ${_}`),L=await $.openStatusCard("restart",j),q=j,D=await $.restart(!0,{announce:!L,onStatus:(M)=>{q=M,$.setStatusCard(L,M)}}),F=D?q.startsWith("✅")?q:$.withWorktreeInstructionNotice(K?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):q.startsWith("❌")?q:"❌ 重启失败";await $.closeStatusCard(L,D?$.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"),_="\uD83E\uDDF9 清空并启动新会话",j=await $.restart(!1,{announce:!K,onStatus:(L)=>{_=L,$.setStatusCard(K,L)}});await $.closeStatusCard(K,j?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):_.startsWith("❌")?_:"❌ 清空失败")}return!0}}var $M,PJ;var DJ=R(()=>{e();I();$M=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"]]),PJ=new Set});function R0($,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 G2($){switch($){case"delegated":return"委派任务";case"subagent":return"子 Agent";case"background":return"后台进程"}}function VG($){switch($){case"delegated":return"\uD83E\uDDE0";case"subagent":return"\uD83E\uDD16";case"background":return"⚙️"}}var YG;var FJ=R(()=>{YG=["delegated","subagent","background"]});function m9($,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)}…
137
137
 
138
138
  ${Q}`}function j6($,Z=8000){if($.length<=Z)return $;let J="_结果超过卡片安全上限,已截断。_",Q=Math.max(1,Z-J.length-2);return`${$.slice(0,Q)}…
139
139
 
140
- ${J}`}function XG($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function JU($,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 HG($){return $==="workflow"||$==="monitor"}function _$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function MJ($){return $.some((Z)=>!_$(Z))}function c9($,Z,J=Date.now()){let Q=JU(Z.task_type,Z.subagent_type),Y=(z)=>z.id===Z.task_id||!!Z.tool_use_id&&z.toolUseId===Z.tool_use_id,V=$.active.some(Y),X=$.pending.some(Y);if(V||X){let z=(G)=>({...G,..._$(G)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type: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(z)],pending:$.pending.filter((G)=>!Y(G))};return{active:V?$.active.map((G)=>Y(G)?z(G):G):$.active,pending:X?$.pending.map((G)=>Y(G)?z(G):G):$.pending}}let H={id:Z.task_id,displayId:Z.tool_use_id??Z.task_id,toolUseId:Z.tool_use_id,type:Q,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...HG(Q)?{isBackgrounded:!0}:{}};return Q==="subagent"||HG(Q)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function OJ($,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 AJ($,Z){let J=$.pending.findIndex((X)=>X.id===Z.task_id),Q=Z.patch;if(Q.is_backgrounded===!0&&J>=0){let X=$.pending[J],H={...X,isBackgrounded:!0,status:Q.status??X.status,description:Q.description??X.description,error:Q.error??X.error,endTime:Q.end_time??X.endTime};return{active:[...$.active,H],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Y||V){let X=(H)=>({...H,status:Q.status??H.status,description:Q.description??H.description,error:Q.error??H.error,isBackgrounded:Q.is_backgrounded??H.isBackgrounded,endTime:Q.end_time??H.endTime});return{active:Y?$.active.map((H)=>H.id===Z.task_id?X(H):H):$.active,pending:V?$.pending.map((H)=>H.id===Z.task_id?X(H):H):$.pending}}return $}function NJ($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function L6($,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 q6($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>QU){J=Q+1;break}return J===0?$:$.slice(J)}function YU($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return l2(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 VU($,Z){let Q=((typeof $==="string"?$:Array.isArray($)?$.map((Y)=>typeof Y?.text==="string"?Y.text:JSON.stringify(Y)).join(`
141
- `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Q.slice(0,80)}`:Q.slice(0,80)}function RJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>G.toolUseId===Z?{...G,steps:q6([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${YU(Q,Y)}`.trim()}])}:G);return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function TJ($,Z,J,Q,Y,V){let X=$.active.some((G)=>G.id===Z),H=$.pending.some((G)=>G.id===Z);if(!X&&!H)return $;let z=(G)=>G.map((W)=>{if(W.id!==Z)return W;if(Y==="started")return{...W,steps:q6([...W.steps,{toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()}])};let K=!1,_=W.steps.map((j)=>{if(K||j.toolUseId!==J)return j;return K=!0,{...j,brief:V?`${j.brief} ${V}`:j.brief}});if(!K&&V)_.push({toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()});return{...W,steps:q6(_)}});return{active:X?z($.active):$.active,pending:H?z($.pending):$.pending}}function xJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>{if(G.toolUseId!==Z)return G;let W=!1,K=G.steps.map((_)=>{if(W||_.toolUseId!==J)return _;return W=!0,{..._,brief:`${_.brief} → ${VU(Q,Y)}`}});return{...G,steps:q6(K)}});return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function l9($){return $.type==="subagent"?"subagent":"background"}function BG($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of XU)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:`${R0((Q+1)*600,"down")}+`,nextDelayMs:Y-Z}}function N4($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=UJ){let Q=Math.floor((J-UJ)/zG),Y=UJ+(Q+1)*zG;return{label:`${R0((10+Q*5)*60,"down")}+`,nextDelayMs:Y-J}}return{label:R0(Math.floor(J/1000)),nextDelayMs:KG}}return BG($)}function GG($){return $.subagentType??$.workflowName??WG[$.type]}function HU($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function zU($){let Z=G2(l9($)),J=WG[$.type],Q=[`**${Z}${J!==Z?` · ${J}`:""}**${GG($)!==J?` · ${GG($)}`:""}${_$($)?` · 用时 ${R0(HU($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Q.push(`⚠ ${$.error}`);if($.summary)Q.push("",`**${_$($)?"结果":"进度"}**`,_$($)?j6($.summary):m9($.summary));if($.prompt)Q.push("","**任务说明**",m9($.prompt));if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3))Q.push(`- ${Y.brief}`)}else if($.lastToolName)Q.push("",`最近动作:${$.lastToolName}`);return $0(Q.join(`
142
- `))}function P6($){let Z=G2(l9($)),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 EJ($){return{tag:"collapsible_panel",element_id:p9.panel($.id),header:{title:{tag:"plain_text",content:P6($)}},expanded:!1,elements:[{tag:"markdown",element_id:p9.body($.id),content:zU($)}]}}var p9,QU=1000,WG,XU,KG=1000,UJ=600000,zG=300000;var SJ=R(()=>{h0();$8();FJ();p9={panel:($)=>`bg_${XG($)}`,body:($)=>`bgb_${XG($)}`};WG={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"};XU=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as GU}from"node:events";import{join as WU,isAbsolute as KU,extname as BU,basename as _U}from"node:path";import{readFile as jU}from"node:fs/promises";function qU($){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 D6=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),CJ,bJ;var _G=R(()=>{B0();u1();b9();I();CJ={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};bJ=class bJ extends GU{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=D6();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"};U0(Z,"dsh",$.workDir),this.launchKind=Z.kind;let J={...process.env,...$.hostEnv};this.runtime=new $6({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:WU($.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(CJ).find((Q)=>CJ[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)=>!KU(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(`
143
- `)}],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(BU(V).toLowerCase()))continue;let X=await jU(V);J.push({type:"image",mediaType:qU(X),name:_U(V),data:X.toString("base64")})}await this.runtime.request("session/prompt",{mode:"auto",content:J}),this.pendingInputs--}).catch((J)=>this.fail(J))}sendInterrupt(){this.runtime.request("session/cancel").catch(($)=>this.fail($))}sendPermissionResponse($,Z,J){let Q=String($),Y=this.questionInputs.get(Q);if(!Y)throw Error(`unknown DSH question: ${Q}`);let V=J?.updatedInput?.answers,X=Z==="allow"?Y.map((H)=>{let z=V?.[H.question]??V?.[H.id];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${H.question}`);let G=H.options?.find((W)=>W.label===z);return{id:H.id,selected:G?[z]:[],...G?{}:{custom:z}}}):void 0;this.runtime.request("question/answer",{id:Q,answers:X,...Z==="deny"?{error:J?.denyMessage??"User declined the question"}:{}}).then(()=>{this.questionInputs.delete(Q),this.emit("tool_result",{tool_use_id:Q,content:JSON.stringify({answers:X}),is_error:Z==="deny",parentToolUseId:null})}).catch((H)=>this.fail(H))}sendHookResponse(){throw Error("DSH does not issue hook callback requests")}async listModels(){return await this.runtime.initialize(),this.models=await this.runtime.request("model/list",{models:[this.lastModel??this.opts.model]}),this.models.map(($)=>({id:$.model,model:$.model,displayName:$.display,description:"DeepSeek Harness",hidden:!1,isDefault:$.isDefault,defaultReasoningEffort:$.defaultEffort,supportedReasoningEfforts:$.efforts.map((Z)=>({reasoningEffort:Z,description:""}))}))}async setModelSettings($,Z){if(!F0(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 l1}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={...D6(),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}
140
+ ${J}`}function XG($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function JM($,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 HG($){return $==="workflow"||$==="monitor"}function _$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function UJ($){return $.some((Z)=>!_$(Z))}function c9($,Z,J=Date.now()){let Q=JM(Z.task_type,Z.subagent_type),Y=(z)=>z.id===Z.task_id||!!Z.tool_use_id&&z.toolUseId===Z.tool_use_id,V=$.active.some(Y),X=$.pending.some(Y);if(V||X){let z=(G)=>({...G,..._$(G)?{status:"running",startedAt:J,endTime:void 0,summary:void 0,error:void 0,usage:void 0,steps:[]}:{},id:Z.task_id,type: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(z)],pending:$.pending.filter((G)=>!Y(G))};return{active:V?$.active.map((G)=>Y(G)?z(G):G):$.active,pending:X?$.pending.map((G)=>Y(G)?z(G):G):$.pending}}let H={id:Z.task_id,displayId:Z.tool_use_id??Z.task_id,toolUseId:Z.tool_use_id,type:Q,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...HG(Q)?{isBackgrounded:!0}:{}};return Q==="subagent"||HG(Q)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function OJ($,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 AJ($,Z){let J=$.pending.findIndex((X)=>X.id===Z.task_id),Q=Z.patch;if(Q.is_backgrounded===!0&&J>=0){let X=$.pending[J],H={...X,isBackgrounded:!0,status:Q.status??X.status,description:Q.description??X.description,error:Q.error??X.error,endTime:Q.end_time??X.endTime};return{active:[...$.active,H],pending:$.pending.filter((z)=>z.id!==Z.task_id)}}let Y=$.active.some((X)=>X.id===Z.task_id),V=J>=0;if(Y||V){let X=(H)=>({...H,status:Q.status??H.status,description:Q.description??H.description,error:Q.error??H.error,isBackgrounded:Q.is_backgrounded??H.isBackgrounded,endTime:Q.end_time??H.endTime});return{active:Y?$.active.map((H)=>H.id===Z.task_id?X(H):H):$.active,pending:V?$.pending.map((H)=>H.id===Z.task_id?X(H):H):$.pending}}return $}function NJ($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function L6($,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 q6($){let Z=0,J=0;for(let Q=$.length-1;Q>=0;Q--)if(Z+=$[Q].brief.length+5,Z>QM){J=Q+1;break}return J===0?$:$.slice(J)}function YM($,Z){let J=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":return l2(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 VM($,Z){let Q=((typeof $==="string"?$:Array.isArray($)?$.map((Y)=>typeof Y?.text==="string"?Y.text:JSON.stringify(Y)).join(`
141
+ `):JSON.stringify($))??"MISS").replace(/\s+/g," ").trim();return Z?`❌ ${Q.slice(0,80)}`:Q.slice(0,80)}function RJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>G.toolUseId===Z?{...G,steps:q6([...G.steps,{toolUseId:J,tool:Q,brief:`${Q} ${YM(Q,Y)}`.trim()}])}:G);return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function TJ($,Z,J,Q,Y,V){let X=$.active.some((G)=>G.id===Z),H=$.pending.some((G)=>G.id===Z);if(!X&&!H)return $;let z=(G)=>G.map((W)=>{if(W.id!==Z)return W;if(Y==="started")return{...W,steps:q6([...W.steps,{toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()}])};let K=!1,_=W.steps.map((j)=>{if(K||j.toolUseId!==J)return j;return K=!0,{...j,brief:V?`${j.brief} ${V}`:j.brief}});if(!K&&V)_.push({toolUseId:J,tool:Q,brief:`${Q} ${V}`.trim()});return{...W,steps:q6(_)}});return{active:X?z($.active):$.active,pending:H?z($.pending):$.pending}}function xJ($,Z,J,Q,Y){if(!Z)return $;let V=$.active.some((z)=>z.toolUseId===Z),X=$.pending.some((z)=>z.toolUseId===Z);if(!V&&!X)return $;let H=(z)=>z.map((G)=>{if(G.toolUseId!==Z)return G;let W=!1,K=G.steps.map((_)=>{if(W||_.toolUseId!==J)return _;return W=!0,{..._,brief:`${_.brief} → ${VM(Q,Y)}`}});return{...G,steps:q6(K)}});return{active:V?H($.active):$.active,pending:X?H($.pending):$.pending}}function l9($){return $.type==="subagent"?"subagent":"background"}function BG($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let V of XM)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:`${R0((Q+1)*600,"down")}+`,nextDelayMs:Y-Z}}function N4($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=MJ){let Q=Math.floor((J-MJ)/zG),Y=MJ+(Q+1)*zG;return{label:`${R0((10+Q*5)*60,"down")}+`,nextDelayMs:Y-J}}return{label:R0(Math.floor(J/1000)),nextDelayMs:KG}}return BG($)}function GG($){return $.subagentType??$.workflowName??WG[$.type]}function HM($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function zM($){let Z=G2(l9($)),J=WG[$.type],Q=[`**${Z}${J!==Z?` · ${J}`:""}**${GG($)!==J?` · ${GG($)}`:""}${_$($)?` · 用时 ${R0(HM($)/1000)}`:""}`,$.description||"说明 MISS"];if($.error)Q.push(`⚠ ${$.error}`);if($.summary)Q.push("",`**${_$($)?"结果":"进度"}**`,_$($)?j6($.summary):m9($.summary));if($.prompt)Q.push("","**任务说明**",m9($.prompt));if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3))Q.push(`- ${Y.brief}`)}else if($.lastToolName)Q.push("",`最近动作:${$.lastToolName}`);return $0(Q.join(`
142
+ `))}function P6($){let Z=G2(l9($)),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 EJ($){return{tag:"collapsible_panel",element_id:p9.panel($.id),header:{title:{tag:"plain_text",content:P6($)}},expanded:!1,elements:[{tag:"markdown",element_id:p9.body($.id),content:zM($)}]}}var p9,QM=1000,WG,XM,KG=1000,MJ=600000,zG=300000;var SJ=R(()=>{h0();$8();FJ();p9={panel:($)=>`bg_${XG($)}`,body:($)=>`bgb_${XG($)}`};WG={subagent:"子 Agent",shell:"后台命令",monitor:"监控",workflow:"工作流",unknown:"任务"};XM=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});import{EventEmitter as GM}from"node:events";import{join as WM,isAbsolute as KM,extname as BM,basename as _M}from"node:path";import{readFile as jM}from"node:fs/promises";function qM($){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 D6=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),CJ,bJ;var _G=R(()=>{B0();u1();b9();I();CJ={bash:"Bash",read:"Read",write:"Write",edit:"Edit",glob:"Glob",grep:"Grep"};bJ=class bJ extends GM{opts;provider="dsh";tokenSourceId;launchKind;sessionId=null;lastAssistantUuid=null;lastCompletedTurnId=null;lastModel;lastEffort;lastUsage=null;lastTotalUsage=null;lastResult=D6();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 $6({cwd:$.workDir,env:$.transformEnv?$.transformEnv(J):J,profile:$.profile,...$.managedSkillPluginPath?{managedSkillDir:WM($.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(CJ).find((Q)=>CJ[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)=>!KM(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(`
143
+ `)}],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(BM(V).toLowerCase()))continue;let X=await jM(V);J.push({type:"image",mediaType:qM(X),name:_M(V),data:X.toString("base64")})}await this.runtime.request("session/prompt",{mode:"auto",content:J}),this.pendingInputs--}).catch((J)=>this.fail(J))}sendInterrupt(){this.runtime.request("session/cancel").catch(($)=>this.fail($))}sendPermissionResponse($,Z,J){let Q=String($),Y=this.questionInputs.get(Q);if(!Y)throw Error(`unknown DSH question: ${Q}`);let V=J?.updatedInput?.answers,X=Z==="allow"?Y.map((H)=>{let z=V?.[H.question]??V?.[H.id];if(typeof z!=="string")throw Error(`missing answer to DSH question: ${H.question}`);let G=H.options?.find((W)=>W.label===z);return{id:H.id,selected:G?[z]:[],...G?{}:{custom:z}}}):void 0;this.runtime.request("question/answer",{id:Q,answers:X,...Z==="deny"?{error:J?.denyMessage??"User declined the question"}:{}}).then(()=>{this.questionInputs.delete(Q),this.emit("tool_result",{tool_use_id:Q,content:JSON.stringify({answers:X}),is_error:Z==="deny",parentToolUseId:null})}).catch((H)=>this.fail(H))}sendHookResponse(){throw Error("DSH does not issue hook callback requests")}async listModels(){return await this.runtime.initialize(),this.models=await this.runtime.request("model/list",{models:[this.lastModel??this.opts.model]}),this.models.map(($)=>({id:$.model,model:$.model,displayName:$.display,description:"DeepSeek Harness",hidden:!1,isDefault:$.isDefault,defaultReasoningEffort:$.defaultEffort,supportedReasoningEfforts:$.efforts.map((Z)=>({reasoningEffort:Z,description:""}))}))}async setModelSettings($,Z){if(!F0(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 l1}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={...D6(),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}
144
144
 
145
- ${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=D6(),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=CJ[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={...D6(),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 LU}from"node:events";function FU($,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 PU="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",DU,kJ=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),wJ;var jG=R(()=>{D0();WJ();U$();I();DU=["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"];wJ=class wJ extends LU{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??kJ()}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??Y6}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 H=Q.candidates.some((z)=>z.state==="miss"&&!z.duplicateOf)?"Codex 账号检查失败,无法自动选账号(MISS)":Q.candidates.length?"没有符合条件的 Codex 账号":"没有配置 Codex 账号";throw Error(`${H}${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??FU)(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,K1(this,Q.selected.account.id,!1),this.wire(V),this.emit("codex_account_changed",{accountId:Q.selected.account.id,previousAccountId:Y,diagnostics:Q.candidates.filter((z)=>z.usage!==null&&z.state==="miss"&&!z.duplicateOf).map((z)=>`${z.account.name}:${z.reason}`)}),this.lifetime.signal.throwIfAborted(),V.sendInitialize();let H=V.initializationPromise?.();if(!H)throw Error("Codex 初始化未提供确认事务");if(await H,this.lifetime.signal.throwIfAborted(),this.lastSession=V.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:V.sessionId});if(!this.recovery)this.drainInputs()}wire($){let Z=null;for(let J of DU)$.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=n1(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 z of this.backgroundTasks)this.emit("bg_task_settled",{task_id:z,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 H=Z.accepted?PU:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(H),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...kJ(),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={...kJ(),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 u9($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new wJ({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,_,j,L,q)=>u9({...$,model:L,effort:q,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:K,launch:_})}),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=s2(J,Y),X=!Q&&J&&k$(J,Y);if(!Q&&J&&Y&&!X)throw Error(`model is not present in token source ${J.id}: ${Y}`);if(!Q&&X&&(X.unavailableReason||!X.efforts.length||$.effort!==void 0&&!X.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Y}/${$.effort??"MISS"}`);let H=!Q&&J&&Y?J.resolveSpawnModel(Y):Y;if(Y&&!H)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Y}`);let z=J?(W)=>J.spawnEnv(W,H):void 0;if($.provider==="dsh"){if(!J||!H||!F0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new bJ({...$,model:H,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(u5(),!A0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new F8({workDir:$.workDir,model:H,effort:$.effort,...$.launch?.kind==="fresh"||!$.launch?{}:{resumeSessionId:$.launch.source.sessionId,...$.launch.kind==="fork"?{forkSession:!0}:{},...$.launch.kind==="fork"&&$.launch.through?.provider==="claude"?{resumeSessionAt:$.launch.through.id}:{}},...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},...$.profile?{profile:$.profile}:{},...J?{settingSources:J.settingSources??["project","local"]}:{},...J?.claudeSettings?{settings:J.claudeSettings}:{},...J?.validateClaudeAccount?{validateAccount:J.validateClaudeAccount}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!W$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let G=new i2({workDir:$.workDir,model:H,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z,...J?.codexApiProvider?{apiProvider:J.codexApiProvider}:{}});if(!J?.codexApiProvider)K1(G,Z);return{process:G,sourceRevision:V}}var yJ=R(()=>{B0();_G();e2();j1();Q0();D0();jG()});function F6($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function qG($){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 W2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function vJ($){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 MU($){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 OU($){let Z=W2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${vJ($.file.url)})`:Z,Q=$.status==="failed"?`<font color='red'>${W2($.error??"交付失败")}</font>`:`<font color='grey'>${qG($.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:MU($.name)}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[{tag:"markdown",content:`${J}
146
- ${Q}`}]}]}}function fJ($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Q=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Y=$.folderAccessReady&&$.folder?vJ($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],X=V.slice(0,UU),H=V.slice(X.length).filter((z)=>z.status==="failed").length;return{schema:"2.0",config:{update_multi:!0,width_mode:"default",summary:{content:`交付文件 · ${Q}`}},header:{title:{tag:"plain_text",content:"\uD83D\uDCC1 交付文件"},subtitle:{tag:"plain_text",content:`${$.projectName} · ${new Date($.createdAt).toLocaleString("zh-CN",{hour12:!1})}`},template:Z||!J?"blue":"red"},body:{padding:"16px",vertical_spacing:"16px",elements:[{tag:"markdown",content:`**本次交付 · ${Q}**`},{tag:"column_set",element_id:C.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(OU),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${H?`中有 ${H} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${W2($.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 hJ($){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}**
145
+ ${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=D6(),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=CJ[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={...D6(),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 LM}from"node:events";function FM($,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 PM="上一轮因当前账号额度耗尽而中断,现已切换账号。请基于本会话已有记录继续完成用户尚未完成的任务,保留已完成的修改和工具结果。执行有副作用的操作前先确认现状,不要重复已完成的操作。",DM,kJ=()=>({cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:null,subtype:null,is_error:!1}),wJ;var jG=R(()=>{D0();WJ();M$();I();DM=["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"];wJ=class wJ extends LM{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??kJ()}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??Y6}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 H=Q.candidates.some((z)=>z.state==="miss"&&!z.duplicateOf)?"Codex 账号检查失败,无法自动选账号(MISS)":Q.candidates.length?"没有符合条件的 Codex 账号":"没有配置 Codex 账号";throw Error(`${H}${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??FM)(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,K1(this,Q.selected.account.id,!1),this.wire(V),this.emit("codex_account_changed",{accountId:Q.selected.account.id,previousAccountId:Y,diagnostics:Q.candidates.filter((z)=>z.usage!==null&&z.state==="miss"&&!z.duplicateOf).map((z)=>`${z.account.name}:${z.reason}`)}),this.lifetime.signal.throwIfAborted(),V.sendInitialize();let H=V.initializationPromise?.();if(!H)throw Error("Codex 初始化未提供确认事务");if(await H,this.lifetime.signal.throwIfAborted(),this.lastSession=V.sessionId,this.starting=!1,this.ownRetry=null,!this.initialized)this.initialized=!0,this.emit("init",{session_id:V.sessionId});if(!this.recovery)this.drainInputs()}wire($){let Z=null;for(let J of DM)$.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=n1(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 z of this.backgroundTasks)this.emit("bg_task_settled",{task_id:z,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 H=Z.accepted?PM:Z.rejectedInput;this.recovery=null,this.inner.sendUserText(H),this.drainInputs()}fail($){let Z=$ instanceof Error?$:Error(String($));this.fault=Z,this.ownRetry=null,this.inputs.length=0,this.result={...kJ(),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={...kJ(),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 u9($){if($.provider==="codex"&&$.tokenSourceId==="codex-sub"&&$.codexAccountPreference!==void 0){if(!$.model&&!$.codexAccountPreference)throw Error("Codex 自动选号需要明确模型");return{process:new wJ({model:$.model??"",effort:$.effort,preferred:$.codexAccountPreference,workDir:$.workDir,launch:$.launch??{kind:"fresh"},create:(K,_,j,L,q)=>u9({...$,model:L,effort:q,codexAccountPreference:void 0,codexManualAccount:j,codexAccountId:K,launch:_})}),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=s2(J,Y),X=!Q&&J&&k$(J,Y);if(!Q&&J&&Y&&!X)throw Error(`model is not present in token source ${J.id}: ${Y}`);if(!Q&&X&&(X.unavailableReason||!X.efforts.length||$.effort!==void 0&&!X.efforts.includes($.effort)))throw Error(`model effort unavailable: ${J.id}/${Y}/${$.effort??"MISS"}`);let H=!Q&&J&&Y?J.resolveSpawnModel(Y):Y;if(Y&&!H)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${Y}`);let z=J?(W)=>J.spawnEnv(W,H):void 0;if($.provider==="dsh"){if(!J||!H||!F0($.effort))throw Error("DSH requires a configured source, model and valid effort");return{process:new bJ({...$,model:H,effort:$.effort,tokenSourceId:J.id,transformEnv:z}),sourceRevision:V}}if($.provider==="claude"){if(u5(),!A0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new F8({workDir:$.workDir,model:H,effort:$.effort,...$.launch?.kind==="fresh"||!$.launch?{}:{resumeSessionId:$.launch.source.sessionId,...$.launch.kind==="fork"?{forkSession:!0}:{},...$.launch.kind==="fork"&&$.launch.through?.provider==="claude"?{resumeSessionAt:$.launch.through.id}:{}},...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},...$.profile?{profile:$.profile}:{},...J?{settingSources:J.settingSources??["project","local"]}:{},...J?.claudeSettings?{settings:J.claudeSettings}:{},...J?.validateClaudeAccount?{validateAccount:J.validateClaudeAccount}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv}),sourceRevision:V}}if($.effort!==void 0&&!W$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);let G=new i2({workDir:$.workDir,model:H,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:J?.id??null,transformEnv:z,hostEnv:$.hostEnv,serviceName:$.serviceName,codexAccountId:Z,...J?.codexApiProvider?{apiProvider:J.codexApiProvider}:{}});if(!J?.codexApiProvider)K1(G,Z);return{process:G,sourceRevision:V}}var yJ=R(()=>{B0();_G();e2();j1();Q0();D0();jG()});function F6($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}function qG($){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 W2($){return $.replace(/[&<>\[\]()*_`!\\#|~]/g,(Z)=>`&#${Z.charCodeAt(0)};`).replace(/[\r\n]+/g," ")}function vJ($){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 OM($){let Z=W2($.name),J=$.status==="ready"&&$.file?.url?`[${Z}](${vJ($.file.url)})`:Z,Q=$.status==="failed"?`<font color='red'>${W2($.error??"交付失败")}</font>`:`<font color='grey'>${qG($.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}
146
+ ${Q}`}]}]}}function fJ($){let Z=$.files.filter((z)=>z.status==="ready").length,J=$.files.filter((z)=>z.status==="failed").length,Q=`${Z} 个文件${J?` · ${J} 个未完成`:""}`,Y=$.folderAccessReady&&$.folder?vJ($.folder.url):void 0,V=[...$.files.filter((z)=>z.status==="failed"),...$.files.filter((z)=>z.status!=="failed")],X=V.slice(0,MM),H=V.slice(X.length).filter((z)=>z.status==="failed").length;return{schema:"2.0",config:{update_multi:!0,width_mode:"default",summary:{content:`交付文件 · ${Q}`}},header:{title:{tag:"plain_text",content:"\uD83D\uDCC1 交付文件"},subtitle:{tag:"plain_text",content:`${$.projectName} · ${new Date($.createdAt).toLocaleString("zh-CN",{hour12:!1})}`},template:Z||!J?"blue":"red"},body:{padding:"16px",vertical_spacing:"16px",elements:[{tag:"markdown",content:`**本次交付 · ${Q}**`},{tag:"column_set",element_id:C.fileDeliveryList,flex_mode:"none",background_style:"grey-50",columns:[{tag:"column",width:"weighted",weight:1,padding:"12px",vertical_spacing:"12px",elements:[...X.map(OM),...$.files.length>X.length?[{tag:"markdown",content:`<font color='grey'>其余 ${$.files.length-X.length} 个文件${H?`中有 ${H} 个未完成,原因已单独提示;已上传文件`:""}请打开文件夹查看</font>`}]:[]]}]},...$.error?[{tag:"markdown",content:`<font color='red'>${W2($.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 hJ($){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}**
147
147
  工作目录:${W2($.workDir)}
148
- 群:${W2($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:W2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${W2($.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:vJ($.settings.folder.url)}]}]:[]]}}}var UU=12;var U6=R(()=>{h0()});function M6($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function O6($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function AU($,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 PG($,Z,J){let Q=AU($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function LG($){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 A6($,Z){let J=LG($);return Z!=null&&Z>0?`${J}/${LG(Z)}`:`${J}/--`}function DG($,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 gJ($,Z,J){let Q=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Q||"MISS"}/${J||"MISS"}`}function R6($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function NU($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function RU($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function N6($){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 FG($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function MG($){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 TU($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${MG($)}`}function IJ($){return typeof $==="number"&&Number.isFinite($)?$:null}function xU($){let Z=IJ($.startedAtMs),J=IJ($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${R0((J-Z)/1000)}`}function EU($){let Z=IJ($);return Z==null?null:N6(Z)}function SU($,Z){if(!Z)return["压缩中..."];let J=[],Q=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Y=EU($.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 mJ($,Z,J){if($==null||!Number.isFinite($))return null;let Q=PG($,Z,J);return Q?`${Q.used}% · ${A6($,Z)}`:"--"}function pJ($){let Z=N6($?.input_tokens??Number.NaN),J=N6($?.cache_read_input_tokens??Number.NaN),Q=N6($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function d9($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",V=Y?"✅":"⏳",X=Y?xU(Q):"",H=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,z=SU(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
149
- `)}]}}function OG($,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(`- ${NU(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(`
150
- `)}function cJ($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:TU($,J)}},expanded:!1,elements:[{tag:"markdown",content:OG($,Z,J)}]}}function i9($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${MG($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:OG($,Z)}]}}function lJ($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${FG($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${R0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${FG($.status)}: ${RU($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
151
- `)}]}}function T6($){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:$0(X)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...V,{tag:"markdown",element_id:C.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function AG($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function CU($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function bU($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let V=$.options[Y],X=V.description?` · ${$0(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:`**${$0(V.label)}**${X}`}]})}return Q}function UG($,Z,J,Q){if($.length===0)return null;let Y=$.length,V=[];for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let z=AG(H,X,Y),G=Q.get(X);if(G){let W=CU(H,G),K=[`**✅ ${z}**`,`**回答**:${W}`];V.push({tag:"markdown",content:K.join(`
152
- `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),H.options.length>0)V.push(...bU(H,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function R4($,Z,J,Q="\uD83E\uDD14",Y){let V=J.length,X=Y?.answered??new Map,H=Y?.currentIdx,z=H===void 0&&X.size>0,G=[],W;if(Y?.waitingFor)W=Y.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",G.push({tag:"markdown",content:Y.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){W=`${Q} 已回答 · ${V}/${V}`,G.push(...UG(J,Z,H,X)??[]);let K=[...X.values()].reverse().find((_)=>_.user)?.user;if(K)G.push({tag:"markdown",content:`
153
- *— 由 ${K} 回答*`})}else if(H!==void 0&&J[H])W=`${Q} 等你确认 · ${H+1}/${V}`,G.push(...UG(J,Z,H,X)??[]);else if(W=`${Q} 等你确认`,J[0])G.push({tag:"markdown",content:`**${AG(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!z&&!Y?.waitingFor,elements:G}}var NG=R(()=>{h0()});import{isAbsolute as uJ,relative as kU}from"node:path";function E6($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function S6($){return $==="write_stdin"||$.endsWith(".write_stdin")}function yU($){return E6($)||S6($)}function C6($){return $==="FileChange"||$==="fileChange"}function a9($){return $==="WebSearch"||$==="webSearch"}function b6($){return $==="WebFetch"||$==="webFetch"}function sJ($){return $==="MCP"}function o9($){return $==="ImageGeneration"||$==="imageGeneration"}function tJ($){return $==="Agent"||$==="Task"}function k6($){return $==="Read"}function w6($){return $==="Write"}function y6($){return $==="Edit"||$==="NotebookEdit"}function v6($){return $==="MultiEdit"}function rJ($){return $==="Glob"||$==="Grep"||$==="LS"}function f6($){return $==="TodoWrite"}function h6($){return $==="ExitPlanMode"}function I6($){return $.startsWith(TG)}function xG($){return I6($)?$.slice(TG.length):$}function K2($){if(I6($))return"服务端工具";if(C6($))return"文件变更";if(a9($))return"网页搜索";if(b6($))return"网页读取";if(o9($))return"图片生成";if(k6($))return"读取文件";if(w6($))return"写入文件";if(y6($)||v6($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(f6($))return"更新待办";if(h6($))return"确认计划";if($==="Task")return"子任务";return yU($)?"Bash":$}function x1($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(I6($))return J(vU($,Z),80);if(!Z||typeof Z!=="object")return"";if(E6($))return fU(Z);if(S6($))return hU(Z);if(C6($))return J(mU(Z),80);if(a9($))return J(uG(Z),80);if(b6($))return J(nU(Z),80);if(sJ($))return J(oU(Z),80);if(o9($))return J(tU(Z),80);if(tJ($))return J(rU(Z),80);if(k6($))return J(pU(Z),80);if(w6($))return J(cU(Z),80);if(y6($))return J(lU(Z),80);if(v6($))return J(uU(Z),80);if(rJ($))return J(dU($,Z),80);if(f6($))return J(iU(Z),80);if(h6($))return J(s9(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 vU($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:xG($),Q=s9(Z?.input);return Q?`${J}: ${Q}`:J}function fU($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=SG($);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(l2(Q),46)}`}function EG($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function hU($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${EG($)}${J}`}function SG($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=O5(Z);return{description:Q.description||J,command:Q.command}}function X$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
148
+ 群:${W2($.groupName)}`},{tag:"markdown",content:"同一工作目录的群共享交付方式,BTW / FK 沿用此设置;WT 使用独立目录设置。云空间文件夹及权限仍各群独立。"},...$.notice?[{tag:"markdown",content:W2($.notice)}]:[],...$.error?[{tag:"markdown",content:`<font color='red'>${W2($.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:vJ($.settings.folder.url)}]}]:[]]}}}var MM=12;var M6=R(()=>{h0()});function U6($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function O6($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function AM($,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 PG($,Z,J){let Q=AM($,Z,J??12000);if(Q==null)return null;return{used:Math.min(100,Math.max(0,100-Q)),remaining:Q}}function LG($){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 A6($,Z){let J=LG($);return Z!=null&&Z>0?`${J}/${LG(Z)}`:`${J}/--`}function DG($,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 gJ($,Z,J){let Q=Z?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"");return`${$} · ${Q||"MISS"}/${J||"MISS"}`}function R6($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function NM($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function RM($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function N6($){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 FG($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function UG($){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 TM($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${UG($)}`}function IJ($){return typeof $==="number"&&Number.isFinite($)?$:null}function xM($){let Z=IJ($.startedAtMs),J=IJ($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${R0((J-Z)/1000)}`}function EM($){let Z=IJ($);return Z==null?null:N6(Z)}function SM($,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 mJ($,Z,J){if($==null||!Number.isFinite($))return null;let Q=PG($,Z,J);return Q?`${Q.used}% · ${A6($,Z)}`:"--"}function pJ($){let Z=N6($?.input_tokens??Number.NaN),J=N6($?.cache_read_input_tokens??Number.NaN),Q=N6($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Q}`}function d9($,Z,J){let Q=Z&&typeof Z==="object"?Z:{},Y=Q.phase==="end"||Q.phase==="event",V=Y?"✅":"⏳",X=Y?xM(Q):"",H=`${V} \uD83D\uDEA8 上下文压缩 #${$+1}${X}`,z=SM(Q,Y);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:z.join(`
149
+ `)}]}}function OG($,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(`- ${NM(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(`
150
+ `)}function cJ($,Z,J="",Q){return{tag:"collapsible_panel",element_id:Q,header:{title:{tag:"plain_text",content:TM($,J)}},expanded:!1,elements:[{tag:"markdown",content:OG($,Z,J)}]}}function i9($,Z,J){let Q=$.length>0?`\uD83D\uDCCB 当前计划 · ${UG($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Q}},expanded:!0,elements:[{tag:"markdown",content:OG($,Z)}]}}function lJ($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Q=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Y=[`**\uD83C\uDFAF 当前目标** · ${FG($.status)}`,"",$.objective,"",`- 用量: ${J}${Q} tokens`,`- 用时: ${R0($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${FG($.status)}: ${RM($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Y.join(`
151
+ `)}]}}function T6($){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:$0(X)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...V,{tag:"markdown",element_id:C.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function AG($,Z,J){let Q=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Q}`}function CM($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function bM($,Z,J){let Q=[];for(let Y=0;Y<$.options.length;Y++){let V=$.options[Y],X=V.description?` · ${$0(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:`**${$0(V.label)}**${X}`}]})}return Q}function MG($,Z,J,Q){if($.length===0)return null;let Y=$.length,V=[];for(let X=0;X<$.length;X++){let H=$[X];if(!H)continue;let z=AG(H,X,Y),G=Q.get(X);if(G){let W=CM(H,G),K=[`**✅ ${z}**`,`**回答**:${W}`];V.push({tag:"markdown",content:K.join(`
152
+ `)});continue}if(X===J){if(V.push({tag:"markdown",content:`**\uD83E\uDD14 ${z}**`}),H.options.length>0)V.push(...bM(H,Z,X));V.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}V.push({tag:"markdown",content:`**⏳ ${z}**`})}return V}function R4($,Z,J,Q="\uD83E\uDD14",Y){let V=J.length,X=Y?.answered??new Map,H=Y?.currentIdx,z=H===void 0&&X.size>0,G=[],W;if(Y?.waitingFor)W=Y.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",G.push({tag:"markdown",content:Y.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(z){W=`${Q} 已回答 · ${V}/${V}`,G.push(...MG(J,Z,H,X)??[]);let K=[...X.values()].reverse().find((_)=>_.user)?.user;if(K)G.push({tag:"markdown",content:`
153
+ *— 由 ${K} 回答*`})}else if(H!==void 0&&J[H])W=`${Q} 等你确认 · ${H+1}/${V}`,G.push(...MG(J,Z,H,X)??[]);else if(W=`${Q} 等你确认`,J[0])G.push({tag:"markdown",content:`**${AG(J[0],0,V||1)}**`});return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:W}},expanded:!z&&!Y?.waitingFor,elements:G}}var NG=R(()=>{h0()});import{isAbsolute as uJ,relative as kM}from"node:path";function E6($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function S6($){return $==="write_stdin"||$.endsWith(".write_stdin")}function yM($){return E6($)||S6($)}function C6($){return $==="FileChange"||$==="fileChange"}function a9($){return $==="WebSearch"||$==="webSearch"}function b6($){return $==="WebFetch"||$==="webFetch"}function sJ($){return $==="MCP"}function o9($){return $==="ImageGeneration"||$==="imageGeneration"}function tJ($){return $==="Agent"||$==="Task"}function k6($){return $==="Read"}function w6($){return $==="Write"}function y6($){return $==="Edit"||$==="NotebookEdit"}function v6($){return $==="MultiEdit"}function rJ($){return $==="Glob"||$==="Grep"||$==="LS"}function f6($){return $==="TodoWrite"}function h6($){return $==="ExitPlanMode"}function I6($){return $.startsWith(TG)}function xG($){return I6($)?$.slice(TG.length):$}function K2($){if(I6($))return"服务端工具";if(C6($))return"文件变更";if(a9($))return"网页搜索";if(b6($))return"网页读取";if(o9($))return"图片生成";if(k6($))return"读取文件";if(w6($))return"写入文件";if(y6($)||v6($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(f6($))return"更新待办";if(h6($))return"确认计划";if($==="Task")return"子任务";return yM($)?"Bash":$}function x1($,Z){let J=(Q,Y)=>Q.length>Y?Q.slice(0,Y)+"…":Q;if(I6($))return J(vM($,Z),80);if(!Z||typeof Z!=="object")return"";if(E6($))return fM(Z);if(S6($))return hM(Z);if(C6($))return J(mM(Z),80);if(a9($))return J(uG(Z),80);if(b6($))return J(nM(Z),80);if(sJ($))return J(oM(Z),80);if(o9($))return J(tM(Z),80);if(tJ($))return J(rM(Z),80);if(k6($))return J(pM(Z),80);if(w6($))return J(cM(Z),80);if(y6($))return J(lM(Z),80);if(v6($))return J(uM(Z),80);if(rJ($))return J(dM($,Z),80);if(f6($))return J(iM(Z),80);if(h6($))return J(s9(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:xG($),Q=s9(Z?.input);return Q?`${J}: ${Q}`:J}function fM($){let Z=(V,X)=>V.length>X?V.slice(0,X)+"…":V,J=SG($);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(l2(Q),46)}`}function EG($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function hM($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${EG($)}${J}`}function SG($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Q=O5(Z);return{description:Q.description||J,command:Q.command}}function X$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
154
154
  ${$}
155
- ${J}`}function Q1($,Z=wU,J=""){if($.length<=Z)return X$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,X$(`${Q}
155
+ ${J}`}function Q1($,Z=wM,J=""){if($.length<=Z)return X$($,J);let Q=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,X$(`${Q}
156
156
  ... output 已截断 ...`,J)].join(`
157
157
  `)}function u($){return"`"+String($??"").replace(/`/g,"'")+"`"}function j$($,Z=3000){return X$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function s9($){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 CG($,Z,J){let Q=SG($),Y=Q.command,V=Q.description,X=[];if(V)X.push(`**目的**: ${V}`);let H=$?.cwd??$?.workdir;if(H)X.push(`**cwd**: ${u(H)}`);if($?.source)X.push(`**source**: ${u($.source)}`);if(X.length>0)X.push("");if(X.push("**命令**"),X.push(X$(Y||"(空命令)","bash")),J)X.push(""),X.push(J);if(Z!=null)X.push(""),X.push("---"),X.push("**output:**"),X.push(Q1(Z));return X.join(`
158
158
  `)}function bG($,Z,J){let Q=[],Y=$?.session_id??$?.sessionId;if(Q.push(`**操作**: ${EG($)}`),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(X$(V))}if(J)Q.push(""),Q.push(J);if(Z!=null)Q.push(""),Q.push("---"),Q.push("**output:**"),Q.push(Q1(Z));return Q.join(`
159
- `)}function kG($){return Array.isArray($?.changes)?$.changes:[]}function wG($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function n9($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&uJ(J)&&uJ(Z)){let Q=kU(Z,J);if(Q&&!Q.startsWith("..")&&!uJ(Q))return Q}return J}function IU($){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 yG($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function iJ($){let Z=IU($);if(yG($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function nJ($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function aJ($){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 vG($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function oJ($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function gU($){return $.length>1800?$.slice(0,1800)+`
160
- ... diff 已截断 ...`:$}function mU($){let Z=kG($),J=wG($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?n9($.grantRoot):"";if(z&&G)return`${z} · ${G}`;return z||(G?`申请修改 ${G}`:"")}let Q=Z.map((z)=>aJ(nJ(z))).reduce(vG,{added:0,removed:0}),Y=oJ(Q),V=[...new Set(Z.map(iJ))],X=n9(Z[0]?.path,J),H=Y?` · ${Y}`:"";if(Z.length===1)return`${V[0]} ${X}${H}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${H}`}function fG($,Z,J){let Q=kG($),Y=wG($),V=[];if(Q.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)V.push(`**原因**: ${G}`);if($?.grantRoot)V.push(`**范围**: ${u(n9($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(X$(Z.slice(0,3000)));return V.length>0?V.join(`
161
- `):X$(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((G)=>aJ(nJ(G))).reduce(vG,{added:0,removed:0}),H=oJ(X);if(V.push(`**文件**: ${Q.length} 个`),H)V.push(`**行数**: ${H}`);if($?.status)V.push(`**状态**: ${u($.status)}`);let z=Q.slice(0,5);for(let G of z){let W=nJ(G),K=oJ(aJ(W)),_=n9(G?.path,Y),j=K?`**${iJ(G)}** ${u(_)} · ${K}`:`**${iJ(G)}** ${u(_)}`;V.push(""),V.push(j);let L=yG(G);if(L)V.push(`来自 ${u(n9(L,Y))}`);V.push(W?X$(gU(W),"diff"):"_无 diff 内容_")}if(Q.length>z.length)V.push(""),V.push(`还有 ${Q.length-z.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
162
- `)}function E1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function pU($){let Z=E1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function cU($){let Z=E1($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function lU($){let Z=E1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function uU($){let Z=E1($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function dU($,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 hG($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function iU($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let V=hG(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 nU($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function T4($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(Q1(Z,1200))}function IG($,Z,J){let Q=[],Y=E1($);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(`
159
+ `)}function kG($){return Array.isArray($?.changes)?$.changes:[]}function wG($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function n9($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&uJ(J)&&uJ(Z)){let Q=kM(Z,J);if(Q&&!Q.startsWith("..")&&!uJ(Q))return Q}return J}function IM($){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 yG($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function iJ($){let Z=IM($);if(yG($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function nJ($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function aJ($){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 vG($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function oJ($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function gM($){return $.length>1800?$.slice(0,1800)+`
160
+ ... diff 已截断 ...`:$}function mM($){let Z=kG($),J=wG($);if(Z.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"",G=$?.grantRoot?n9($.grantRoot):"";if(z&&G)return`${z} · ${G}`;return z||(G?`申请修改 ${G}`:"")}let Q=Z.map((z)=>aJ(nJ(z))).reduce(vG,{added:0,removed:0}),Y=oJ(Q),V=[...new Set(Z.map(iJ))],X=n9(Z[0]?.path,J),H=Y?` · ${Y}`:"";if(Z.length===1)return`${V[0]} ${X}${H}`;return`${Z.length} 个文件 · ${V.join("/")} · ${X} 等${H}`}function fG($,Z,J){let Q=kG($),Y=wG($),V=[];if(Q.length===0){let G=typeof $?.reason==="string"?$.reason.trim():"";if(G)V.push(`**原因**: ${G}`);if($?.grantRoot)V.push(`**范围**: ${u(n9($.grantRoot))}`);if(J)V.push(""),V.push(J);if(Z!=null)V.push(""),V.push("---"),V.push("**output:**"),V.push(X$(Z.slice(0,3000)));return V.length>0?V.join(`
161
+ `):X$(JSON.stringify($??{},null,2).slice(0,2000))}let X=Q.map((G)=>aJ(nJ(G))).reduce(vG,{added:0,removed:0}),H=oJ(X);if(V.push(`**文件**: ${Q.length} 个`),H)V.push(`**行数**: ${H}`);if($?.status)V.push(`**状态**: ${u($.status)}`);let z=Q.slice(0,5);for(let G of z){let W=nJ(G),K=oJ(aJ(W)),_=n9(G?.path,Y),j=K?`**${iJ(G)}** ${u(_)} · ${K}`:`**${iJ(G)}** ${u(_)}`;V.push(""),V.push(j);let L=yG(G);if(L)V.push(`来自 ${u(n9(L,Y))}`);V.push(W?X$(gM(W),"diff"):"_无 diff 内容_")}if(Q.length>z.length)V.push(""),V.push(`还有 ${Q.length-z.length} 个文件未展开显示。`);if(J)V.push(""),V.push(J);return V.join(`
162
+ `)}function E1($){return String($?.file_path??$?.path??$?.notebook_path??"")}function pM($){let Z=E1($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function cM($){let Z=E1($),J=typeof $?.content==="string"?$.content:"",Q=J?J.split(/\r?\n/).length:0;return Z&&Q?`${Z} · ${Q} 行`:Z}function lM($){let Z=E1($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function uM($){let Z=E1($),J=Array.isArray($?.edits)?$.edits.length:0,Q=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Q}`:`批量编辑${Q}`}function dM($,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 hG($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function iM($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Y of Z){let V=hG(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 nM($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function T4($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(Q1(Z,1200))}function IG($,Z,J){let Q=[],Y=E1($);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(`
163
163
  `):j$($??{},2000)}function gG($,Z,J){let Q=[],Y=E1($),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(Q1(V,1200))}if(J)Q.push(""),Q.push(J);return T4(Q,Z),Q.length>0?Q.join(`
164
164
  `):j$($??{},2000)}function mG($,Z,J){let Q=[],Y=E1($);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(Q1($.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(Q1(V,800));if(J)Q.push(""),Q.push(J);return T4(Q,Z),Q.length>0?Q.join(`
165
165
  `):j$($??{},2000)}function pG($,Z,J){let Q=[],Y=E1($),V=Array.isArray($?.edits)?$.edits:[];if(Y)Q.push(`**路径**: ${u(Y)}`);Q.push(`**编辑**: ${V.length} 处`);for(let[X,H]of V.slice(0,5).entries()){if(Q.push(""),Q.push(`**#${X+1}${H?.replace_all?" · 全局替换":""}**`),typeof H?.old_string==="string")Q.push("查找:"),Q.push(Q1(H.old_string,500));if(typeof H?.new_string==="string")Q.push("替换为:"),Q.push(Q1(H.new_string,500))}if(V.length>5)Q.push(""),Q.push(`还有 ${V.length-5} 处编辑未展开显示。`);if(J)Q.push(""),Q.push(J);return T4(Q,Z),Q.join(`
166
166
  `)}function cG($,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 T4(Y,J),Y.join(`
167
167
  `)}function lG($,Z,J){let Q=Array.isArray($?.todos)?$.todos:[],Y=[`**待办**: ${Q.length} 项`];for(let V of Q.slice(0,12)){let X=hG(V?.status),H=String(V?.content??V?.activeForm??"").trim()||"(空)";Y.push(`- ${X}: ${H}`)}if(Q.length>12)Y.push(`- 还有 ${Q.length-12} 项未显示`);if(J)Y.push(""),Y.push(J);return T4(Y,Z),Y.join(`
168
- `)}function eJ($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function $Q($,Z){return eJ(Z)??$?.action??{}}function ZQ($,Z){let J=$Q($,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 JQ($,Z){let J=$Q($,Z);return String(J?.url??$?.url??"")}function uG($){let Z=ZQ($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=JQ($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function aU($,Z){let J=ZQ($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=JQ($,Z);if(Q)return Q;return uG($)}function dG($,Z,J){let Q=$Q($,Z),Y=ZQ($,Z),V=JQ($,Z),X=[],H=typeof Q?.type==="string"?Q.type:"";if(H==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let z of Y.slice(0,6))X.push(`- ${u(z)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(H==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${u(V)}`)}else if(H==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${u(V)}`);if(Q?.pattern)X.push(`**关键词**: ${u(Q.pattern)}`)}else if(X.push(`**动作**: ${H?u(H):"网页搜索"}`),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(X$(Z.slice(0,3000),"json"));return X.join(`
168
+ `)}function eJ($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function $Q($,Z){return eJ(Z)??$?.action??{}}function ZQ($,Z){let J=$Q($,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 JQ($,Z){let J=$Q($,Z);return String(J?.url??$?.url??"")}function uG($){let Z=ZQ($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=JQ($,null);if(J)return J;let Q=$?.action?.type;return typeof Q==="string"&&Q!=="other"?Q:""}function aM($,Z){let J=ZQ($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Q=JQ($,Z);if(Q)return Q;return uG($)}function dG($,Z,J){let Q=$Q($,Z),Y=ZQ($,Z),V=JQ($,Z),X=[],H=typeof Q?.type==="string"?Q.type:"";if(H==="search"||Y.length>0){if(X.push("**动作**: 搜索"),Y.length>0){X.push(""),X.push("**查询**");for(let z of Y.slice(0,6))X.push(`- ${u(z)}`);if(Y.length>6)X.push(`- 还有 ${Y.length-6} 条未显示`)}}else if(H==="open_page"){if(X.push("**动作**: 打开页面"),V)X.push(`**URL**: ${u(V)}`)}else if(H==="find_in_page"){if(X.push("**动作**: 页内查找"),V)X.push(`**URL**: ${u(V)}`);if(Q?.pattern)X.push(`**关键词**: ${u(Q.pattern)}`)}else if(X.push(`**动作**: ${H?u(H):"网页搜索"}`),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(X$(Z.slice(0,3000),"json"));return X.join(`
169
169
  `)}function iG($,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 T4(Q,Z),Q.join(`
170
- `)}function oU($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=s9($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function nG($,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(j$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let V=eJ(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((H)=>typeof H?.text==="string"?H.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
170
+ `)}function oM($){let Z=String($?.server??""),J=String($?.tool??""),Q=Z&&J?`${Z}.${J}`:J||Z,Y=s9($?.arguments);return Y&&Q?`${Q}: ${Y}`:Q||Y}function nG($,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(j$(Y,2000))}if(J)Q.push(""),Q.push(J);if(Z!=null){let V=eJ(Z);if(Q.push(""),Q.push("---"),Q.push("**结果**"),V&&Array.isArray(V.content)){let X=V.content.map((H)=>typeof H?.text==="string"?H.text:"").filter(Boolean);if(X.length>0)Q.push(X.join(`
171
171
  `).slice(0,3000));if(V.structuredContent)Q.push(""),Q.push("**structuredContent**"),Q.push(j$(V.structuredContent,2000));if(X.length===0&&!V.structuredContent)Q.push(j$(V,3000))}else Q.push(V?j$(V,3000):X$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
172
- `):j$($??{},2000)}function sU($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${u(typeof Z?.tool==="string"&&Z.tool?Z.tool:xG($))}`],V=Z?.input;if(V&&typeof V==="object")if(Y.push(""),Y.push("**input**"),Object.keys(V).length>0)Y.push(j$(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(Q1(J,3000));return Y.join(`
173
- `)}function tU($){return typeof $?.status==="string"?$.status:""}function aG($,Z,J,Q){let Y=[];if($?.status)Y.push(`**状态**: ${u($.status)}`);if($?.prompt)Y.push("","**提示词**",X$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Y.push("",$.prompt?"**实际提示词**":"**提示词**",X$(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(`
174
- `):j$($??{},2000)}function rU($){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 x6($,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=eJ(Z);Q.push(Y?j$(Y,3000):X$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
175
- `):j$($??{},2000)}function p$($,Z,J,Q,Y="⏳",V,X){let H=a9(Z)&&Q!=null?aU(J,Q):x1(Z,J),z=H.length>80?H.slice(0,80)+"…":H,G=K2(Z),W=z?`${Y} \uD83D\uDD27 ${G}: ${z}`:`${Y} \uD83D\uDD27 ${G}`,K=V?`
172
+ `):j$($??{},2000)}function sM($,Z,J,Q){let Y=["**类型**: 模型服务端内置工具",`**tool**: ${u(typeof Z?.tool==="string"&&Z.tool?Z.tool:xG($))}`],V=Z?.input;if(V&&typeof V==="object")if(Y.push(""),Y.push("**input**"),Object.keys(V).length>0)Y.push(j$(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(Q1(J,3000));return Y.join(`
173
+ `)}function tM($){return typeof $?.status==="string"?$.status:""}function aG($,Z,J,Q){let Y=[];if($?.status)Y.push(`**状态**: ${u($.status)}`);if($?.prompt)Y.push("","**提示词**",X$(String($.prompt)));if($?.revisedPrompt){if($.revisedPrompt!==$.prompt)Y.push("",$.prompt?"**实际提示词**":"**提示词**",X$(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(`
174
+ `):j$($??{},2000)}function rM($){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 x6($,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=eJ(Z);Q.push(Y?j$(Y,3000):X$(Z.slice(0,3000)))}return Q.length>0?Q.join(`
175
+ `):j$($??{},2000)}function p$($,Z,J,Q,Y="⏳",V,X){let H=a9(Z)&&Q!=null?aM(J,Q):x1(Z,J),z=H.length>80?H.slice(0,80)+"…":H,G=K2(Z),W=z?`${Y} \uD83D\uDD27 ${G}: ${z}`:`${Y} \uD83D\uDD27 ${G}`,K=V?`
176
176
 
177
- ${V}`:"",_=E6(Z)?CG(J,Q,V):S6(Z)?bG(J,Q,V):I6(Z)?sU(Z,J,Q,V):C6(Z)?fG(J,Q,V):a9(Z)?dG(J,Q,V):b6(Z)?iG(J,Q,V):sJ(Z)?nG(J,Q,V):o9(Z)?aG(J,Q,V,X):k6(Z)?IG(J,Q,V):w6(Z)?gG(J,Q,V):y6(Z)?mG(J,Q,V):v6(Z)?pG(J,Q,V):rJ(Z)?cG(Z,J,Q,V):f6(Z)?lG(J,Q,V):h6(Z)?x6({prompt:s9(J)||"提交计划"},Q,V):tJ(Z)?x6(J,Q,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
177
+ ${V}`:"",_=E6(Z)?CG(J,Q,V):S6(Z)?bG(J,Q,V):I6(Z)?sM(Z,J,Q,V):C6(Z)?fG(J,Q,V):a9(Z)?dG(J,Q,V):b6(Z)?iG(J,Q,V):sJ(Z)?nG(J,Q,V):o9(Z)?aG(J,Q,V,X):k6(Z)?IG(J,Q,V):w6(Z)?gG(J,Q,V):y6(Z)?mG(J,Q,V):v6(Z)?pG(J,Q,V):rJ(Z)?cG(Z,J,Q,V):f6(Z)?lG(J,Q,V):h6(Z)?x6({prompt:s9(J)||"提交计划"},Q,V):tJ(Z)?x6(J,Q,V):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+K+(Q!=null?`
178
178
  ---
179
179
  **output:**
180
180
  \`\`\`
181
181
  `+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:$0(_)},...o9(Z)&&X?[{tag:"img",img_key:X,alt:{tag:"plain_text",content:"生成的图片"},scale_type:"fit_horizontal",preview:!0}]:[]]}}function t9($,Z){let J=Z.length,Q=Z.some((z)=>z.isError),Y=Z.every((z)=>z.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let z=RG(Z[0]);return z?`${V} \uD83D\uDD27 编辑文件: ${z}`:`${V} \uD83D\uDD27 编辑文件`})():`${V} \uD83D\uDD27 编辑文件 · ${J} 次`,H=Z.map((z)=>{let G=RG(z);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:$0(H.join(`
182
182
  `))}]}}function RG($){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 r9($,Z){let J=Z.length,Q=Z.some((z)=>z.isError),Y=Z.every((z)=>z.output!==null),V=Q?"❌":Y?"✅":"⏳",X=J===1?(()=>{let z=x1("Read",Z[0]?.input);return z?`${V} \uD83D\uDD27 Read: ${z}`:`${V} \uD83D\uDD27 Read`})():`${V} \uD83D\uDD27 Read · ${J} 次`,H=Z.map((z)=>`\`${String(z.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:C.tool($),header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:$0(H.join(`
183
- `))}]}}function QQ($,Z,J,Q){let Y=x1(Z,J),V=K2(Z),X=Y?`\uD83D\uDD10 等审批 · ${V}: ${Y}`:`\uD83D\uDD10 等审批 · ${V}`,H=E6(Z)?CG(J,null):S6(Z)?bG(J,null):C6(Z)?fG(J,null):a9(Z)?dG(J,null):b6(Z)?iG(J,null):sJ(Z)?nG(J,null):o9(Z)?aG(J,null):k6(Z)?IG(J,null):w6(Z)?gG(J,null):y6(Z)?mG(J,null):v6(Z)?pG(J,null):rJ(Z)?cG(Z,J,null):f6(Z)?lG(J,null):h6(Z)?x6({prompt:s9(J)||"提交计划"},null):tJ(Z)?x6(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:H},{tag:"column_set",columns:[dJ("✅ 允许","primary",Q,"allow"),dJ("♾️ 始终允许","default",Q,"allow_always"),dJ("❌ 拒绝","danger",Q,"deny")]}]}}function dJ($,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 wU=300,TG="server_tool:";var oG=R(()=>{h0();$8()});import{execFile as eU}from"node:child_process";import{readFileSync as YQ,statfsSync as $M,statSync as sG}from"node:fs";import{cpus as ZM,homedir as JM}from"node:os";import{promisify as QM}from"node:util";function VM(){try{let $=YQ("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:ZM().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return B(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function XM(){try{let $=YQ("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));return X?parseInt(X[1],10)*1024:0},J=Z("MemTotal"),Q=Z("MemAvailable");if(!J)return null;let Y=Math.max(0,J-Q);return{totalBytes:J,availBytes:Q,usedBytes:Y,percent:Math.round(Y/J*100)}}catch($){return B(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function tG($,Z){try{let J=$M(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 HM(){let $=[],Z=tG("/","/");if(Z)$.push(Z);let J=JM();if(J&&J!=="/"){let Q=!1;try{let Y=sG("/"),V=sG(J);Q=Y.dev===V.dev}catch{}if(!Q){let Y=tG("$HOME",J);if(Y)$.push(Y)}}return $}function zM(){try{let $=YQ("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function rG($,Z=2000){try{let{stdout:J}=await YM("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function eG($){return $W.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function GM(){let $=await rG(["list-units","--type=service","--all","--no-legend","--plain",...$W.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
184
- `).map((z)=>z.trim()).filter((z)=>z.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let z of Z){let W=z.replace(/^●\s*/,"").split(/\s+/)[0];if(!W)continue;if(!eG(W))continue;J.push(W)}if(J.length===0)return{services:[],error:null};let Q=await rG(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=zM(),V=Q.split(/\n\s*\n/),X=[],H=(z)=>{let G=parseInt(z??"0",10);if(G<=0||Y===null)return null;return Math.max(0,Y-G/1e6)};for(let z of V){let G={};for(let K of z.split(`
185
- `)){let _=K.indexOf("=");if(_<=0)continue;G[K.slice(0,_)]=K.slice(_+1)}let W=G.Id??"";if(!eG(W))continue;X.push({name:W.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:H(G.ActiveEnterTimestampMonotonic),stateAgoSec:H(G.StateChangeTimestampMonotonic)})}return X.sort((z,G)=>z.name.localeCompare(G.name)),{services:X,error:null}}async function ZW(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=VM(),Z=XM(),J=HM(),{services:Q,error:Y}=await GM();return{cpu:$,mem:Z,disks:J,services:Q,servicesError:Y}}var YM,$W,e9="cc-* / codex-*";var VQ=R(()=>{I();YM=QM(eU),$W=["cc-","codex-"]});function g6($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function WM($){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 KM($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Q=`${g6(J)} ${WM($.percent)}`;if($.kind==="monthly")return Q;if($.unreportedFull)return`${Q}(满窗)`;return`${Q}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?I$($.resetsAt):"MISS"}`}function JW($){if(!$)return"加载中…";if($.state==="not_applicable")return"—";if($.state!=="ok"){let Q=$.state==="no_credentials"?"未登录或未配置":$.state==="rate_limited"?"API 限频":($.reason??"查询失败").replace(/^Claude 原生额度接口未返回 rate_limits 数据$/,"原生接口未返回额度");return`<font color='red'>MISS · ${g6(Q.slice(0,100))}</font>`}let Z=(Q,Y)=>{if(!Number.isFinite(Q))return"MISS";return`${Y==="USD"?"$":Y==="CNY"?"¥":g6(Y)} ${Q.toFixed(2)}`};if($.kind==="balance")return`余额 ${$.balance?Z($.balance.remaining,$.balance.currency):"MISS"}`;if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${Z($.quota.remaining,$.quota.currency)} / ${Z($.quota.limit,$.quota.currency)}`;let J=$.windows.map(KM);if(!J.length)J.push("额度 MISS");if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function QW($){return{tag:"markdown",text_size:"notation",content:`**${g6($.label)}** ${JW($.usage)}`}}var YW=()=>{};function Z3($,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:Z3($.title,$.status)}]}}}function VW($){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 BM($){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 $3($){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 LM($){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 PM($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${e9} _n/a_`].join(`
186
- `);let Z=[];if($.cpu){let{cores:J,load1:Q,load5:Y,load15:V}=$.cpu;Z.push(`**负载** ${Q.toFixed(2)} / ${Y.toFixed(2)} / ${V.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${VW($.mem.usedBytes)}/${VW($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${e9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${e9} _无_`);else{Z.push(`**服务** ${e9} (${$.services.length})`);for(let J of $.services){let Q=qM[J.active]??"·",Y=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${$3(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${$3(Y*1000)}前`);else X.push("从未启动");if(V!=null){let H=J.active==="failed"?"已挂":"已停";X.push(`${H} ${$3(V*1000)}`)}}else if(V!=null)X.push(`已 ${$3(V*1000)}`);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
187
- `)}function DM($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=_M[J.status]??"·",Y=jM[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${$3(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",H=J.codexAccountName===void 0?"":` · Codex:${S1(q$(J.codexAccountName))}`;return` · ${Q} \`${J.name}\` · ${Y}${V}${X}${H}`}).join(`
188
- `)}function m6($,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:DM($)}]}}function FM($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${BQ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
189
- `)}function p6($,Z=C.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:FM($)}}function c6($,Z=C.consoleHost){let J=LM($);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:PM($)}]}}function HQ($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(Q,Y)=>`${Y==="USD"?"$":Y==="CNY"?"¥":`${Y} `}${Q.toFixed(2)}`;if($.kind==="balance")return $.balance?`余额 ${J($.balance.remaining,$.balance.currency)}`:"余额 MISS";if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${J($.quota.remaining,$.quota.currency)} / ${J($.quota.limit,$.quota.currency)}`;if(!$.windows.length)return"额度 MISS";return`额度 ${$.windows.map(UM).join(" · ")}`}function UM($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function J3($){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(QW):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function XW($,Z){return[p6($,Z),m6($),c6($.sysinfo),J3($)]}function l6($){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:XW($)}}}function zQ($){return B2($.sessionName,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${S1($.currentDisplay??"未选择")}
190
- 选账号进入模型选择。`},...["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)=>MM(Q,$.panelId))}]:[]})]})}function MM($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${q$($.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:`**${q$($.display)}**
191
- ${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 GQ($){return B2($.sessionName,HW($))}function WQ($){return B2($.sessionName,i6($))}function Q3($){return B2($.sessionName,n6($),"green")}function Y3($,Z){return{tag:"collapsible_panel",element_id:C.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:q$(Z)}]}}function u6($,Z,J){return B2($,Y3(Z,J),Z?"orange":"red")}function B2($,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 HW($){let Z=NM($.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:[`当前: ${zW($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
192
- `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?OM($.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 OM($,Z){let{sourceId:J,page:Q,totalPages:Y}=Z,V=(X,H)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:X},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:H}}]}]});return[{tag:"markdown",content:`第 ${Q+1} / ${Y} 页`},{tag:"column_set",columns:[...Q>0?[V("上一页",Q-1)]:[],...Q+1<Y?[V("下一页",Q+1)]:[]]}]}function d6($,Z="cancelled"){return B2($,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function KQ($,Z,J){return B2($,{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(`
183
+ `))}]}}function QQ($,Z,J,Q){let Y=x1(Z,J),V=K2(Z),X=Y?`\uD83D\uDD10 等审批 · ${V}: ${Y}`:`\uD83D\uDD10 等审批 · ${V}`,H=E6(Z)?CG(J,null):S6(Z)?bG(J,null):C6(Z)?fG(J,null):a9(Z)?dG(J,null):b6(Z)?iG(J,null):sJ(Z)?nG(J,null):o9(Z)?aG(J,null):k6(Z)?IG(J,null):w6(Z)?gG(J,null):y6(Z)?mG(J,null):v6(Z)?pG(J,null):rJ(Z)?cG(Z,J,null):f6(Z)?lG(J,null):h6(Z)?x6({prompt:s9(J)||"提交计划"},null):tJ(Z)?x6(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:H},{tag:"column_set",columns:[dJ("✅ 允许","primary",Q,"allow"),dJ("♾️ 始终允许","default",Q,"allow_always"),dJ("❌ 拒绝","danger",Q,"deny")]}]}}function dJ($,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 wM=300,TG="server_tool:";var oG=R(()=>{h0();$8()});import{execFile as eM}from"node:child_process";import{readFileSync as YQ,statfsSync as $U,statSync as sG}from"node:fs";import{cpus as ZU,homedir as JU}from"node:os";import{promisify as QU}from"node:util";function VU(){try{let $=YQ("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:ZU().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return B(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function XU(){try{let $=YQ("/proc/meminfo","utf8"),Z=(V)=>{let X=$.match(new RegExp(`^${V}:\\s+(\\d+)\\s*kB`,"m"));return X?parseInt(X[1],10)*1024:0},J=Z("MemTotal"),Q=Z("MemAvailable");if(!J)return null;let Y=Math.max(0,J-Q);return{totalBytes:J,availBytes:Q,usedBytes:Y,percent:Math.round(Y/J*100)}}catch($){return B(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function tG($,Z){try{let J=$U(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 HU(){let $=[],Z=tG("/","/");if(Z)$.push(Z);let J=JU();if(J&&J!=="/"){let Q=!1;try{let Y=sG("/"),V=sG(J);Q=Y.dev===V.dev}catch{}if(!Q){let Y=tG("$HOME",J);if(Y)$.push(Y)}}return $}function zU(){try{let $=YQ("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function rG($,Z=2000){try{let{stdout:J}=await YU("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return B(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function eG($){return $W.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function GU(){let $=await rG(["list-units","--type=service","--all","--no-legend","--plain",...$W.map((z)=>`${z}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
184
+ `).map((z)=>z.trim()).filter((z)=>z.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let z of Z){let W=z.replace(/^●\s*/,"").split(/\s+/)[0];if(!W)continue;if(!eG(W))continue;J.push(W)}if(J.length===0)return{services:[],error:null};let Q=await rG(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Q===null)return{services:[],error:"systemctl show 失败"};let Y=zU(),V=Q.split(/\n\s*\n/),X=[],H=(z)=>{let G=parseInt(z??"0",10);if(G<=0||Y===null)return null;return Math.max(0,Y-G/1e6)};for(let z of V){let G={};for(let K of z.split(`
185
+ `)){let _=K.indexOf("=");if(_<=0)continue;G[K.slice(0,_)]=K.slice(_+1)}let W=G.Id??"";if(!eG(W))continue;X.push({name:W.replace(/\.service$/,""),active:G.ActiveState??"unknown",sub:G.SubState??"",lastActiveAgoSec:H(G.ActiveEnterTimestampMonotonic),stateAgoSec:H(G.StateChangeTimestampMonotonic)})}return X.sort((z,G)=>z.name.localeCompare(G.name)),{services:X,error:null}}async function ZW(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=VU(),Z=XU(),J=HU(),{services:Q,error:Y}=await GU();return{cpu:$,mem:Z,disks:J,services:Q,servicesError:Y}}var YU,$W,e9="cc-* / codex-*";var VQ=R(()=>{I();YU=QU(eM),$W=["cc-","codex-"]});function g6($){return $.replace(/[\r\n]+/g," ").replace(/[&<>\\`*_\[\]~]/g,(Z)=>`&#${Z.charCodeAt(0)};`)}function WU($){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 KU($){let J={fiveHour:"5h",weekly:"周",monthly:"月工具",seven_day_opus:"Opus周",seven_day_sonnet:"Sonnet周",seven_day_oauth_apps:"OAuth周"}[$.kind]??$.label.replace(/\s*周额度$/,"周"),Q=`${g6(J)} ${WU($.percent)}`;if($.kind==="monthly")return Q;if($.unreportedFull)return`${Q}(满窗)`;return`${Q}/${$.resetsAt&&Number.isFinite($.resetsAt.getTime())?I$($.resetsAt):"MISS"}`}function JW($){if(!$)return"加载中…";if($.state==="not_applicable")return"—";if($.state!=="ok"){let Q=$.state==="no_credentials"?"未登录或未配置":$.state==="rate_limited"?"API 限频":($.reason??"查询失败").replace(/^Claude 原生额度接口未返回 rate_limits 数据$/,"原生接口未返回额度");return`<font color='red'>MISS · ${g6(Q.slice(0,100))}</font>`}let Z=(Q,Y)=>{if(!Number.isFinite(Q))return"MISS";return`${Y==="USD"?"$":Y==="CNY"?"¥":g6(Y)} ${Q.toFixed(2)}`};if($.kind==="balance")return`余额 ${$.balance?Z($.balance.remaining,$.balance.currency):"MISS"}`;if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${Z($.quota.remaining,$.quota.currency)} / ${Z($.quota.limit,$.quota.currency)}`;let J=$.windows.map(KU);if(!J.length)J.push("额度 MISS");if($.resetCredits!==void 0)J.push(`重置 ${$.resetCredits===null?"MISS":$.resetCredits}`);return J.join(" · ")}function QW($){return{tag:"markdown",text_size:"notation",content:`**${g6($.label)}** ${JW($.usage)}`}}var YW=()=>{};function Z3($,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:Z3($.title,$.status)}]}}}function VW($){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 BU($){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 $3($){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 LU($){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 PU($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${e9} _n/a_`].join(`
186
+ `);let Z=[];if($.cpu){let{cores:J,load1:Q,load5:Y,load15:V}=$.cpu;Z.push(`**负载** ${Q.toFixed(2)} / ${Y.toFixed(2)} / ${V.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${VW($.mem.usedBytes)}/${VW($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${e9} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${e9} _无_`);else{Z.push(`**服务** ${e9} (${$.services.length})`);for(let J of $.services){let Q=qU[J.active]??"·",Y=J.lastActiveAgoSec,V=J.stateAgoSec,X=[J.active];if(J.active==="active"){if(V!=null)X.push(`已运行 ${$3(V*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Y!=null)X.push(`上次活跃 ${$3(Y*1000)}前`);else X.push("从未启动");if(V!=null){let H=J.active==="failed"?"已挂":"已停";X.push(`${H} ${$3(V*1000)}`)}}else if(V!=null)X.push(`已 ${$3(V*1000)}`);Z.push(` · ${Q} \`${J.name}\` · ${X.join(" · ")}`)}}return Z.join(`
187
+ `)}function DU($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Q=_U[J.status]??"·",Y=jU[J.status]??J.status,V=J.uptimeMs!=null&&J.uptimeMs>0?` · ${$3(J.uptimeMs)}`:"",X=J.isCurrent?" · 当前":"",H=J.codexAccountName===void 0?"":` · Codex:${S1(q$(J.codexAccountName))}`;return` · ${Q} \`${J.name}\` · ${Y}${V}${X}${H}`}).join(`
188
+ `)}function m6($,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:DU($)}]}}function FU($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${BQ($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
189
+ `)}function p6($,Z=C.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:FU($)}}function c6($,Z=C.consoleHost){let J=LU($);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:PU($)}]}}function HQ($){let Z=$?.kind==="balance"?"余额":"额度";if(!$)return`${Z} 加载中…`;if($.state==="not_applicable")return`${Z} —`;if($.state!=="ok")return`${Z} MISS`;let J=(Q,Y)=>`${Y==="USD"?"$":Y==="CNY"?"¥":`${Y} `}${Q.toFixed(2)}`;if($.kind==="balance")return $.balance?`余额 ${J($.balance.remaining,$.balance.currency)}`:"余额 MISS";if($.quota)return $.quota.limit===null?"额度 未设上限":$.quota.remaining===null?"额度 MISS":`额度 ${J($.quota.remaining,$.quota.currency)} / ${J($.quota.limit,$.quota.currency)}`;if(!$.windows.length)return"额度 MISS";return`额度 ${$.windows.map(MU).join(" · ")}`}function MU($){let Z=typeof $.used==="number"&&typeof $.total==="number"?`${$.used}/${$.total}`:$.percent===null?"MISS":`${Math.round($.percent)}%`;return`${$.label} 已用 ${Z}`}function J3($){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(QW):[{tag:"markdown",text_size:"notation",content:"暂无已配置账号"}]}}function XW($,Z){return[p6($,Z),m6($),c6($.sysinfo),J3($)]}function l6($){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:XW($)}}}function zQ($){return B2($.sessionName,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${S1($.currentDisplay??"未选择")}
190
+ 选账号进入模型选择。`},...["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)=>UU(Q,$.panelId))}]:[]})]})}function UU($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${q$($.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:`**${q$($.display)}**
191
+ ${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 GQ($){return B2($.sessionName,HW($))}function WQ($){return B2($.sessionName,i6($))}function Q3($){return B2($.sessionName,n6($),"green")}function Y3($,Z){return{tag:"collapsible_panel",element_id:C.modelPanel,expanded:!0,header:{title:{tag:"plain_text",content:$?"模型设置确认中":"模型设置未完成"}},elements:[{tag:"markdown",content:q$(Z)}]}}function u6($,Z,J){return B2($,Y3(Z,J),Z?"orange":"red")}function B2($,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 HW($){let Z=NU($.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:[`当前: ${zW($.currentModel,$.currentEffort)}`,$.mode==="add"?"显示账号接口中的模型。":"接口模型可隐藏,补录模型可删除。有多个 effort 档位时再选择档位。"].join(`
192
+ `)},...$.models.length?Z:[{tag:"markdown",content:$.editable?$.mode==="add"?"_没有待显示的接口模型_":"_列表为空,可显示接口模型或补录_":"_未返回可用模型列表_"}],...$.pagination?OU($.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 OU($,Z){let{sourceId:J,page:Q,totalPages:Y}=Z,V=(X,H)=>({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:X},type:"default",behaviors:[{type:"callback",value:{kind:"model_page",panel_id:$,source_id:J,page:H}}]}]});return[{tag:"markdown",content:`第 ${Q+1} / ${Y} 页`},{tag:"column_set",columns:[...Q>0?[V("上一页",Q-1)]:[],...Q+1<Y?[V("下一页",Q+1)]:[]]}]}function d6($,Z="cancelled"){return B2($,{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function KQ($,Z,J){return B2($,{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(`
193
193
  `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function V3($,Z,J){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表${J?`
194
- ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function i6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${xM($.model)}`,`当前: ${zW($.currentModel,$.currentEffort)}`].join(`
195
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>RM($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function n6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",S1(GW($.model,$.effort,$.provider)),q$($.scope)].join(`
196
- `)}]}}function AM($,Z,J,Q=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${q$($.displayName)}** · 未配置
194
+ ${J}`:""}`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function i6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${xU($.model)}`,`当前: ${zW($.currentModel,$.currentEffort)}`].join(`
195
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>RU($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function n6($){return{tag:"collapsible_panel",element_id:C.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",S1(GW($.model,$.effort,$.provider)),q$($.scope)].join(`
196
+ `)}]}}function AU($,Z,J,Q=!1){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${q$($.displayName)}** · 未配置
197
197
  ${q$($.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?`**${q$($.displayName)}**`:`**${S1($.model)}**`,V=[$.isDefault?`${BQ($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),X=$.description?`
198
- `+q$(EM($.description,110)):"",H=(G,W)=>({tag:"button",text:{tag:"plain_text",content:W},type:"default",behaviors:[{type:"callback",value:{kind:G,panel_id:Z,source_id:$.sourceId,model:$.model}}]});return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,vertical_align:"center",elements:[{tag:"markdown",content:[Y,$.displayName&&$.displayName!==$.model?S1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
199
- `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[H("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:TM($,Z)}]}],...Q&&J!=="add"?[$.origin==="custom"?H("model_custom_remove","删"):H("model_remove","隐")]:[]]}]}]}function NM($,Z,J,Q=!1){let Y=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((H)=>H.provider==="dsh")}].filter((H)=>H.models.length>0),V=(H)=>H.flatMap((z,G)=>[...G?[{tag:"hr"}]:[],...AM(z,Z,J,Q)]);if(Y.length<=1)return V($);let X=[];for(let H of Y)X.push({tag:"markdown",content:`**${H.title}**`}),X.push(...V(H.models));return X}function RM($,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"?"模型默认":q$(Z.effort)}**`,X,Z.description?q$(Z.description):""].filter(Boolean).join(`
200
- `)}]},{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 TM($,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 xM($){return $.displayName&&$.displayName!==$.model?`${q$($.displayName)} (${S1($.model)})`:S1($.model)}function zW($,Z){return S1(GW($,Z))}function GW($,Z,J){let Q=J&&J!=="codex"?`${BQ(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function BQ($){return c0($??"codex")}function EM($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function q$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function S1($){return"`"+$.replace(/`/g,"\\`")+"`"}function _2($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${R0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${BM($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var _M,jM,qM;var WW=R(()=>{B0();VQ();h0();YW();_M={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},jM={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},qM={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function _Q($){let Z=bM($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:SM($.notice)},body:{elements:[...$.notice?[CM($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(kM)]}}}function SM($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function CM($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
198
+ `+q$(EU($.description,110)):"",H=(G,W)=>({tag:"button",text:{tag:"plain_text",content:W},type:"default",behaviors:[{type:"callback",value:{kind:G,panel_id:Z,source_id:$.sourceId,model:$.model}}]});return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,vertical_align:"center",elements:[{tag:"markdown",content:[Y,$.displayName&&$.displayName!==$.model?S1($.model):"",V.length?V.join(" · "):""].filter(Boolean).join(`
199
+ `)+X}]},{tag:"column",width:"weighted",weight:1,vertical_align:"center",elements:[...J==="add"?[H("model_add","显")]:$.unavailableReason?[{tag:"markdown",content:"**MISS**"}]:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:TU($,Z)}]}],...Q&&J!=="add"?[$.origin==="custom"?H("model_custom_remove","删"):H("model_remove","隐")]:[]]}]}]}function NU($,Z,J,Q=!1){let Y=[{title:"Codex",models:$.filter((H)=>(H.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((H)=>H.provider==="claude")},{title:"DeepSeek Harness",models:$.filter((H)=>H.provider==="dsh")}].filter((H)=>H.models.length>0),V=(H)=>H.flatMap((z,G)=>[...G?[{tag:"hr"}]:[],...AU(z,Z,J,Q)]);if(Y.length<=1)return V($);let X=[];for(let H of Y)X.push({tag:"markdown",content:`**${H.title}**`}),X.push(...V(H.models));return X}function RU($,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"?"模型默认":q$(Z.effort)}**`,X,Z.description?q$(Z.description):""].filter(Boolean).join(`
200
+ `)}]},{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 TU($,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 xU($){return $.displayName&&$.displayName!==$.model?`${q$($.displayName)} (${S1($.model)})`:S1($.model)}function zW($,Z){return S1(GW($,Z))}function GW($,Z,J){let Q=J&&J!=="codex"?`${BQ(J)} · `:"";if($&&Z)return`${Q}${$}/${Z}`;if($)return`${Q}${$}`;if(Z)return`${Q}${Z}`;return"未选择"}function BQ($){return c0($??"codex")}function EU($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function q$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function S1($){return"`"+$.replace(/`/g,"\\`")+"`"}function _2($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec!=null)Z.push(`⏱ ${R0($.durationSec)}`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${BU($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var _U,jU,qU;var WW=R(()=>{B0();VQ();h0();YW();_U={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},jU={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"},qU={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function _Q($){let Z=bU($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:SU($.notice)},body:{elements:[...$.notice?[CU($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(kU)]}}}function SU($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function CU($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
201
201
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
202
- `)}}function bM($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${a6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function kM($){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:`**${a6($.slug)}**
202
+ `)}}function bU($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${a6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function kU($){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:`**${a6($.slug)}**
203
203
  ${Z} · ${J}
204
204
  ${a6($.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 X3($){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,a6($.branch),...$.body?[$.body]:[]].join(`
205
205
  `)}]}}}function a6($){return"`"+$.replace(/`/g,"\\`")+"`"}function qQ($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Q=Z?"temp_fork_select":"temp_back_select",Y=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
206
206
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
207
- 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:wM($.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:`**${FQ(X.ts)}**
207
+ 只回退对话历史,不会回滚 cwd 中的文件。`,V=[];if($.notice)V.push({tag:"markdown",content:wU($.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:`**${FQ(X.ts)}**
208
208
  ${C1(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 LQ($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
209
209
  新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${FQ(J.ts)}**
210
210
  ${C1(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 PQ($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Q=J.body.length>800?J.body.slice(0,800)+`
@@ -216,42 +216,42 @@ ${Q}`}).join(`
216
216
  `):$.bindingState==="unchanged"?[`${jQ($.message)}`,"",`本群原绑定 ${C1(o6($.previousSessionId))};源会话未修改。`].join(`
217
217
  `):[`${jQ($.message)}`,"",`后端返回会话 ${C1(o6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
218
218
  `);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}**`,`**${FQ($.selectedTs)}**${V}`,C1(Y),`源会话 ${C1(o6($.sourceSessionId))}`].join(`
219
- `)},{tag:"markdown",content:X}]}}}function FQ($){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 C1($){return"`"+KW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function o6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function jQ($){return KW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function KW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function wM($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
219
+ `)},{tag:"markdown",content:X}]}}}function FQ($){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 C1($){return"`"+KW($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function o6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function jQ($){return KW($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function KW($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function wU($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
220
220
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
221
221
  `)}function BW($){if(!$||typeof $!=="object")return"";if(typeof $.content==="string")return $.content;if(typeof $.new_string==="string")return $.new_string;if(typeof $.new_source==="string")return $.new_source;if(Array.isArray($.edits))return $.edits.map((Z)=>typeof Z?.new_string==="string"?Z.new_string:"").filter(Boolean).join(`
222
222
  ---
223
- `);return""}function UQ($,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:BW(Z)}]}function OQ($){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?[fM($.notice)]:[],{tag:"markdown",element_id:C.tasklistPanel,content:yM($)},vM($)]}}}function yM($){let Z=[`项目:${MQ($.projectName)}`,`清单:${MQ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
224
- `);if(Z.push("","已启用"),Z.push(`GUID:${MQ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
225
- `)}function vM($){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 fM($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
226
- `).map((J)=>`<font color='${Z}'>${hM(J)||" "}</font>`).join(`
227
- `)}}function MQ($){return"`"+$.replace(/`/g,"\\`")+"`"}function hM($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var _W=R(()=>{h0()});import{createHash as IM}from"node:crypto";function NQ($){let Z=[{tag:"markdown",element_id:C.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
223
+ `);return""}function MQ($,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:BW(Z)}]}function OQ($){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?[fU($.notice)]:[],{tag:"markdown",element_id:C.tasklistPanel,content:yU($)},vU($)]}}}function yU($){let Z=[`项目:${UQ($.projectName)}`,`清单:${UQ($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
224
+ `);if(Z.push("","已启用"),Z.push(`GUID:${UQ($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
225
+ `)}function vU($){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 fU($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
226
+ `).map((J)=>`<font color='${Z}'>${hU(J)||" "}</font>`).join(`
227
+ `)}}function UQ($){return"`"+$.replace(/`/g,"\\`")+"`"}function hU($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var _W=R(()=>{h0()});import{createHash as IU}from"node:crypto";function NQ($){let Z=[{tag:"markdown",element_id:C.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
228
228
  `)}];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)=>`- **${c$(J.display)}**:${c$(J.reason)}`).join(`
229
- `)}]});return Z.push(...$.catalog.map(mM),pM($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function RQ($){return{tag:"collapsible_panel",element_id:s6($.runId),header:{title:{tag:"plain_text",content:t6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${c$($.description??"说明 MISS")}**`,qW($).content,`**任务说明**
229
+ `)}]});return Z.push(...$.catalog.map(mU),pU($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function RQ($){return{tag:"collapsible_panel",element_id:s6($.runId),header:{title:{tag:"plain_text",content:t6($)}},expanded:!1,elements:[{tag:"markdown",content:[`**${c$($.description??"说明 MISS")}**`,qW($).content,`**任务说明**
230
230
  ${$0(m9($.prompt))}`,...$.workers.map((Z)=>jW(Z).content)].join(`
231
231
 
232
- `)}]}}function s6($){return`ar_${IM("sha256").update($).digest("hex").slice(0,16)}`}function TQ($){if($.length===1)return $[0].summary;let Z=$.filter((H)=>H.terminal).length,J=$.filter((H)=>H.status==="failed").length,Q=$.filter((H)=>H.status==="needs_input"||H.status==="paused").length,Y=new Set($.map((H)=>H.kind??"delegated")),V=YG.filter((H)=>Y.has(H));return`${V.length===1?`${VG(V[0])} ${G2(V[0])}`:`\uD83E\uDDE9 运行任务 · ${V.map((H)=>`${G2(H)} ${$.filter((z)=>(z.kind??"delegated")===H).length}`).join(" · ")}`} · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Q?` · 待处理 ${Q}`:""}`}function jW($,Z=gM){let J=cM($),Q=[`模型 ${j2($.model)} · 推理 ${j2($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${R0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Q.push("",c$($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let Y of $.pendingInput.questions)if(Q.push(`- ${c$(Y.question)}`),Y.options.length)Q.push(` 选项:${Y.options.map((V)=>j2(V.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",$0($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",$0(j6($.output,Z)));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3)){let V=Y.tool==="tool error"?"❌":Y.phase==="completed"?"✓":Y.phase==="started"?"→":"·",X=Y.tool==="tool error"?"工具执行失败":Y.tool==="tool result"?"工具执行完成":Y.tool;Q.push(`- ${V} ${j2(X)} ${c$(PW(Y.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${c$($.identityName)}**`,...Q].join(`
232
+ `)}]}}function s6($){return`ar_${IU("sha256").update($).digest("hex").slice(0,16)}`}function TQ($){if($.length===1)return $[0].summary;let Z=$.filter((H)=>H.terminal).length,J=$.filter((H)=>H.status==="failed").length,Q=$.filter((H)=>H.status==="needs_input"||H.status==="paused").length,Y=new Set($.map((H)=>H.kind??"delegated")),V=YG.filter((H)=>Y.has(H));return`${V.length===1?`${VG(V[0])} ${G2(V[0])}`:`\uD83E\uDDE9 运行任务 · ${V.map((H)=>`${G2(H)} ${$.filter((z)=>(z.kind??"delegated")===H).length}`).join(" · ")}`} · 已结束 ${Z}/${$.length}${J?` · 失败 ${J}`:""}${Q?` · 待处理 ${Q}`:""}`}function jW($,Z=gU){let J=cU($),Q=[`模型 ${j2($.model)} · 推理 ${j2($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${R0($.durationMs/1000)}`);if($.status==="queued"&&$.queuedReason)Q.push("",c$($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let Y of $.pendingInput.questions)if(Q.push(`- ${c$(Y.question)}`),Y.options.length)Q.push(` 选项:${Y.options.map((V)=>j2(V.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",$0($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",$0(j6($.output,Z)));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let Y of $.steps.slice(-3)){let V=Y.tool==="tool error"?"❌":Y.phase==="completed"?"✓":Y.phase==="started"?"→":"·",X=Y.tool==="tool error"?"工具执行失败":Y.tool==="tool result"?"工具执行完成":Y.tool;Q.push(`- ${V} ${j2(X)} ${c$(PW(Y.detail,180))}`)}}return{tag:"markdown",content:[`**${J} · ${c$($.identityName)}**`,...Q].join(`
233
233
  `)}}function qW($){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,H=[Y?`执行中 ${Y}`:"",V?`排队 ${V}`:"",Q?`待答 ${Q}`:"",J?`失败 ${J}`:"",X?`已取消 ${X}`:""].filter(Boolean),z=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null;return{tag:"markdown",content:[`**${LW($)}** · 完成 ${Z}/${$.workers.length}`,...H.length?[H.join(" · ")]:[],...z!=null&&Number.isFinite(z)?[`⏱ 用时 ${R0(z/1000)}`]:[],...$.error?[c$($.error)]:[]].join(`
234
- `)}}function t6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${LW($)} · ${PW($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function mM($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${c$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${j2($.id)}
234
+ `)}}function t6($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${LW($)} · ${PW($.description??"说明 MISS",40)}${$.workers.length>1?` · ${Z}/${$.workers.length}`:""}`}function mU($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${c$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${j2($.id)}
235
235
  ${j2($.model)} · 默认 ${j2($.defaultEffort??"MISS")} · ${c$(J)}`].join(`
236
- `)}}function pM($){return{tag:"column_set",columns:[AQ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),AQ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),AQ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function AQ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function cM($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function lM($){return $==="completed"||$==="failed"||$==="cancelled"}function LW($){let Z=G2("delegated");switch($.status){case"completed":return`✅ ${Z}完成`;case"failed":return`❌ ${Z}失败`;case"cancelled":return`\uD83D\uDED1 ${Z}已取消`;case"needs_input":return`❓ ${Z}等待主 Agent 回复`;case"queued":return`⏳ ${Z}等待执行`;case"running":return $.workers.length>0&&$.workers.every((J)=>lM(J.status))?`⏳ ${Z}正在收尾`:`⏳ ${Z}正在执行`}}function j2($){return"`"+$.replace(/`/g,"\\`")+"`"}function c$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function PW($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var gM=8000;var DW=R(()=>{h0();FJ()});function L2($){return uM.has($)?$:null}function r6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function x4($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function q2($){return String($?.subject??$?.content??"").trim()}function xQ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function MW($){return`subj:${$}`}function FW($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function aM($){let Z=q2($);if(!Z)return null;return{id:x4($)||MW(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:xQ($)??"pending"}}function EQ($,Z,J,Q){if(Z==="TaskList"){let Y=r6(Q),V=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(V===null)return $;let X=[];for(let H of V){let z=aM(H);if(z)X.push(z)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let G=r6(Q),W=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,K=$;return Y.forEach((_,j)=>{let L=q2(_);if(!L)return;let q=W?.[j],D=q&&x4(q)||FW(Q??"");K=UW(K,D,L,_)}),K}let V=r6(Q),X=V?.task??V,H=x4(X)||FW(Q??""),z=q2(X)||q2(J);if(!z)return $;return UW($,H,z,J)}if(Z==="TaskUpdate"){let Y=x4(J);if(!Y)return $;let V=xQ(J);if(V==="deleted")return $.filter((H)=>H.id!==Y);let X=q2(J);if($.some((H)=>H.id===Y))return $.map((H)=>H.id===Y?{...H,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:H);return $}if(Z==="TaskGet"){let Y=r6(Q),V=Y?.task??Y,X=x4(V)||x4(J);if(!X)return $;let H=$.find((W)=>W.id===X),z=q2(V)||H?.subject||q2(J);if(!z)return $;let G={id:X,subject:z,description:typeof V?.description==="string"?V.description:H?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:H?.activeForm,status:xQ(V)??H?.status??"pending"};return H?$.map((W)=>W.id===X?G:W):[...$,G]}return $}function UW($,Z,J,Q){let Y=Z||MW(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=iM[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 OW($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let H=parseInt(X,10);return Number.isNaN(H)?Number.MAX_SAFE_INTEGER:H},V=[...J].sort((X,H)=>{let z=Y(X.id)-Y(H.id);return z!==0?z:X.id.localeCompare(H.id)});for(let X of V.slice(0,12)){let H=nM[X.status],z=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${H} ${z||"(空)"}`)}if(V.length>12)Q.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
237
- `)}function k1($,Z,J,Q){let Y=dM[J.name],V=SQ(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:OW(Z,Q)}]}}function P2($){return{tag:"collapsible_panel",element_id:C.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${SQ($)}`}},expanded:!0,elements:[{tag:"markdown",content:OW($)}]}}var uM,dM,iM,nM;var AW=R(()=>{h0();uM=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);dM={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},iM={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},nM={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var L$=R(()=>{h0();U6();NG();oG();WW();_W();DW();AW();SJ()});import{createHash as oM}from"node:crypto";class z3{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(NW($))}async update($,Z=!1,J=!1){await this.updateRow(NW($),Z,!1,J)}syncBackground($,Z,J){return M$($,async()=>{let Q=this.background.get(Z);if(!Q)this.background.set(Z,Q=new Map);let Y=[];for(let V of J){let X=V.displayId??V.toolUseId??V.id,H=Q.get(X);if(H?.task===V&&!H.pendingSettings)continue;let z=H&&_$(H.task)&&!_$(V),G=(H?.version??0)+(z?1:0),W=`background:${Z}:${X}:${G}`,K={key:W,chatId:$,elementId:p9.panel(W),element:EJ({...V,id:W}),summary:P6(V),kind:l9(V),status:V.status,terminal:_$(V)};try{if(!H||z)await this.addRow(K);else{let _=!H.pendingSettings&&tM(H.task,V);if(!await this.updateRow(K,K.terminal,!0,_))continue}Q.set(X,{task:V,version:G})}catch(_){if(this.byTask.get(W)?.rows.get(W)===K)Q.set(X,{task:V,version:G,pendingSettings:!0});Y.push(_)}}if(Y.length)throw AggregateError(Y,Y.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return M$($.chatId,async()=>{if(this.byTask.get($.key)){await this.updateRow($,$.terminal,!0);return}let J=this.tails.get($.chatId);if(J){if(await this.deps.getChatTailMessageId($.chatId)===J.messageId&&this.deps.getElementCount(J.cardId)<sM){let Y=await this.deps.addElementResult(J.cardId,$.element);if(Y.landed){this.attach(J,$),await this.settings(J);return}if(!CQ(Y))throw H3("agent card append",Y)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1,Q=!1){return M$($.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 H=Y.rows.get($.key);if(Q&&!Z&&!$.terminal&&!Y.pendingSettings&&!CQ(X)&&H?.status==="running"&&$.status===H.status&&$.kind===H.kind&&$.summary===H.summary&&$.progressState===H.progressState)return B(`agent: task progress refresh failed task=${$.key}: ${H3("agent task row update",X).message}`),!1;if(!CQ(X)||Y.rows.size===1)throw H3("agent task row update",X);let z=Y;await this.seal(z,!0);let G=this.tails.get($.chatId);if(G)await this.seal(G);Y=await this.create($),z.rows.delete($.key),z.settled.delete($.key);try{let W;if(!await this.deps.deleteElementChecked(z.cardId,$.elementId,(K)=>{W=K})){let K=H3("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(z)}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(H){V.push(String(H))}if(V.length)throw Error(V.join("; "));return!0})}closeChat($){return M$($,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: ${k(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:!1};return this.attach(Y,$),this.tails.set($.chatId,Y),Y}async seal($,Z=!1){if($.sealed=!0,this.tails.get($.chatId)===$)this.tails.delete($.chatId);await this.settings($,!Z)}async settings($,Z=!0){this.deps.cancelSummary($.cardId);let J=$.settled.size===$.rows.size,Q={config:{streaming_mode:!J,summary:{content:TQ([...$.rows.values()])}}},Y=JSON.stringify(Q);if(Y!==$.settingsJson){let V;if($.pendingSettings=!0,!await this.deps.patchSettingsChecked($.cardId,Q,(X)=>{V=X}))throw H3("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 NW($){let{cardMessageId:Z,presentationErrors:J,promptArtifact:Q,...Y}=$;return{key:`run:${$.runId}`,chatId:$.chatId,elementId:s6($.runId),element:RQ($),summary:t6($),kind:"delegated",status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",progressState:oM("sha256").update(JSON.stringify({...Y,workers:Y.workers.map(({steps:V,usage:X,durationMs:H,outputArtifact:z,...G})=>G)})).digest("hex"),attach:(V)=>{$.cardMessageId=V}}}function CQ($){return D4($.failure?.code,$.failure)}function tM($,Z){return $.status==="running"&&Z.status==="running"&&Object.keys({...$,...Z}).every((J)=>J==="steps"||J==="usage"||J==="lastToolName"||$[J]===Z[J])}function H3($,Z){return Error(`${$} MISS: ${k(Z.failure)}`)}var sM=50;var bQ=R(()=>{L$();Z1();t5();I()});function RW(){return new z3(kQ)}var kQ;var wQ=R(()=>{bQ();Z1();e();kQ={sendCard:i,getChatTailMessageId:hZ,convertMessageToCard:h$,recordCardCreated:A$,getElementCount:y9,addElementResult:U4,replaceElementResult:gz,deleteElementChecked:mz,cancelSummary:i0,patchSettingsChecked:C0,dispose:B$}});function rM(){return JSON.stringify([w5(),TX(),u0().map(($)=>[$.id,$.enabled,$.spawnRevision,$.usageAccount]),v.list().map(($)=>[$.id,$.name,$.revision])])}function yQ(){let $=rM();if(G3?.key===$)return G3.promise;let Z=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],J=(H)=>Z.includes(H)?Z.indexOf(H):Z.length,Q=u0().filter((H)=>H.enabled||H.kind==="codex-subscription"&&v.list().some((z)=>z.id!=="default")).sort((H,z)=>J(H.id)-J(z.id)),Y=new Set,V=[];for(let H of Q){if(H.kind==="codex-subscription"){V.push(Q6().then((W)=>W.entries.filter((K)=>!K.duplicateOf).map((K)=>({id:`codex:${K.account.id}`,label:`Codex·${K.account.name}`,usage:_9(K.usage)}))));continue}let z=H.usageAccount?.id??sH(H.id);if(Y.has(z))continue;Y.add(z);let G=H.usageAccount?.label??(z==="glm"?"GLM Coding Plan":z==="deepseek"?"DeepSeek":H.kind==="claude-subscription"?"Claude 订阅":H.display);V.push(Promise.resolve().then(()=>H.readUsage()).catch((W)=>{let K=W instanceof Error?W.message:String(W);return B(`account usage ${z} MISS: ${K}`),{state:"network",windows:[],reason:K}}).then((W)=>[{id:z,label:G,usage:W}]))}let X=Promise.all(V).then((H)=>H.flat()).finally(()=>{if(G3?.promise===X)G3=void 0});return G3={key:$,promise:X},X}var G3;var TW=R(()=>{D0();GJ();M8();Q0();S9();U$();I()});function xW($){let Z=[];for(let J of $.matchAll(eM)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function e6($,Z=process.platform){if(Z!=="win32")return $;let J=$O.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var eM,$O;var vQ=R(()=>{eM=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;$O=/^\/([a-zA-Z])\//});function CW($){if(EW.test($))return{marker:"start",body:$.replace(EW,"")};if(SW.test($))return{marker:"end",body:$.replace(SW,"")};return{marker:"none",body:$}}var EW,SW;var bW=R(()=>{EW=/^>{3,}[ \t]?/,SW=/^<{3,}[ \t]?/});async function kW($,Z,J,Q,Y){let{marker:V,body:X}=CW(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)hQ($,"reopen");return $.multiMsgBuffer=[],fQ($,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}fQ($,X,J,Q,Y);let{multiMsgBuffer:H,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await JO($,H,z),!0}if($.multiMsgBuffer!==null)return fQ($,Z,J,Q,Y),!0;return!1}function fQ($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)ZO($,Y)}function ZO($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await Q$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else g0(Z,J)})()}async function JO($,Z,J){for(let[X,H]of J)if(H)g0(X,H);let Q=Z.filter((X)=>X.text.trim()||X.files.length);if(Q.length===0){B(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await b($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((z)=>`[file: ${z}]`).join(" ")+`
236
+ `)}}function pU($){return{tag:"column_set",columns:[AQ("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),AQ("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),AQ("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function AQ($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function cU($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function lU($){return $==="completed"||$==="failed"||$==="cancelled"}function LW($){let Z=G2("delegated");switch($.status){case"completed":return`✅ ${Z}完成`;case"failed":return`❌ ${Z}失败`;case"cancelled":return`\uD83D\uDED1 ${Z}已取消`;case"needs_input":return`❓ ${Z}等待主 Agent 回复`;case"queued":return`⏳ ${Z}等待执行`;case"running":return $.workers.length>0&&$.workers.every((J)=>lU(J.status))?`⏳ ${Z}正在收尾`:`⏳ ${Z}正在执行`}}function j2($){return"`"+$.replace(/`/g,"\\`")+"`"}function c$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function PW($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var gU=8000;var DW=R(()=>{h0();FJ()});function L2($){return uU.has($)?$:null}function r6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function x4($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function q2($){return String($?.subject??$?.content??"").trim()}function xQ($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function UW($){return`subj:${$}`}function FW($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function aU($){let Z=q2($);if(!Z)return null;return{id:x4($)||UW(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:xQ($)??"pending"}}function EQ($,Z,J,Q){if(Z==="TaskList"){let Y=r6(Q),V=Array.isArray(Y?.tasks)?Y.tasks:Array.isArray(Y)?Y:null;if(V===null)return $;let X=[];for(let H of V){let z=aU(H);if(z)X.push(z)}return X}if(Z==="TaskCreate"){let Y=Array.isArray(J?.tasks)?J.tasks:null;if(Y){let G=r6(Q),W=Array.isArray(G?.tasks)?G.tasks:Array.isArray(G)?G:null,K=$;return Y.forEach((_,j)=>{let L=q2(_);if(!L)return;let q=W?.[j],D=q&&x4(q)||FW(Q??"");K=MW(K,D,L,_)}),K}let V=r6(Q),X=V?.task??V,H=x4(X)||FW(Q??""),z=q2(X)||q2(J);if(!z)return $;return MW($,H,z,J)}if(Z==="TaskUpdate"){let Y=x4(J);if(!Y)return $;let V=xQ(J);if(V==="deleted")return $.filter((H)=>H.id!==Y);let X=q2(J);if($.some((H)=>H.id===Y))return $.map((H)=>H.id===Y?{...H,...V?{status:V}:{},...X?{subject:X}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:H);return $}if(Z==="TaskGet"){let Y=r6(Q),V=Y?.task??Y,X=x4(V)||x4(J);if(!X)return $;let H=$.find((W)=>W.id===X),z=q2(V)||H?.subject||q2(J);if(!z)return $;let G={id:X,subject:z,description:typeof V?.description==="string"?V.description:H?.description,activeForm:typeof V?.activeForm==="string"?V.activeForm:H?.activeForm,status:xQ(V)??H?.status??"pending"};return H?$.map((W)=>W.id===X?G:W):[...$,G]}return $}function MW($,Z,J,Q){let Y=Z||UW(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=iU[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 OW($,Z){let J=$.filter((X)=>X.status!=="deleted"),Q=[`**待办**: ${J.length} 项`],Y=(X)=>{let H=parseInt(X,10);return Number.isNaN(H)?Number.MAX_SAFE_INTEGER:H},V=[...J].sort((X,H)=>{let z=Y(X.id)-Y(H.id);return z!==0?z:X.id.localeCompare(H.id)});for(let X of V.slice(0,12)){let H=nU[X.status],z=X.status==="in_progress"&&X.activeForm?X.activeForm:X.subject;Q.push(`- ${H} ${z||"(空)"}`)}if(V.length>12)Q.push(`- 还有 ${V.length-12} 项未显示`);if(Z)Q.push(""),Q.push(Z);return Q.join(`
237
+ `)}function k1($,Z,J,Q){let Y=dU[J.name],V=SQ(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:OW(Z,Q)}]}}function P2($){return{tag:"collapsible_panel",element_id:C.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${SQ($)}`}},expanded:!0,elements:[{tag:"markdown",content:OW($)}]}}var uU,dU,iU,nU;var AW=R(()=>{h0();uU=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);dU={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},iU={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},nU={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var L$=R(()=>{h0();M6();NG();oG();WW();_W();DW();AW();SJ()});import{createHash as oU}from"node:crypto";class z3{deps;tails=new Map;byTask=new Map;background=new Map;constructor($){this.deps=$}add($){return this.addRow(NW($))}async update($,Z=!1,J=!1){await this.updateRow(NW($),Z,!1,J)}syncBackground($,Z,J){return U$($,async()=>{let Q=this.background.get(Z);if(!Q)this.background.set(Z,Q=new Map);let Y=[];for(let V of J){let X=V.displayId??V.toolUseId??V.id,H=Q.get(X);if(H?.task===V&&!H.pendingSettings)continue;let z=H&&_$(H.task)&&!_$(V),G=(H?.version??0)+(z?1:0),W=`background:${Z}:${X}:${G}`,K={key:W,chatId:$,elementId:p9.panel(W),element:EJ({...V,id:W}),summary:P6(V),kind:l9(V),status:V.status,terminal:_$(V)};try{if(!H||z)await this.addRow(K);else{let _=!H.pendingSettings&&tU(H.task,V);if(!await this.updateRow(K,K.terminal,!0,_))continue}Q.set(X,{task:V,version:G})}catch(_){if(this.byTask.get(W)?.rows.get(W)===K)Q.set(X,{task:V,version:G,pendingSettings:!0});Y.push(_)}}if(Y.length)throw AggregateError(Y,Y.map(String).join("; "))})}releaseBackground($){this.background.delete($)}addRow($){return U$($.chatId,async()=>{if(this.byTask.get($.key)){await this.updateRow($,$.terminal,!0);return}let J=this.tails.get($.chatId);if(J){if(await this.deps.getChatTailMessageId($.chatId)===J.messageId&&this.deps.getElementCount(J.cardId)<sU){let Y=await this.deps.addElementResult(J.cardId,$.element);if(Y.landed){this.attach(J,$),await this.settings(J);return}if(!CQ(Y))throw H3("agent card append",Y)}await this.seal(J)}await this.create($)})}updateRow($,Z=!1,J=!1,Q=!1){return U$($.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 H=Y.rows.get($.key);if(Q&&!Z&&!$.terminal&&!Y.pendingSettings&&!CQ(X)&&H?.status==="running"&&$.status===H.status&&$.kind===H.kind&&$.summary===H.summary&&$.progressState===H.progressState)return B(`agent: task progress refresh failed task=${$.key}: ${H3("agent task row update",X).message}`),!1;if(!CQ(X)||Y.rows.size===1)throw H3("agent task row update",X);let z=Y;await this.seal(z,!0);let G=this.tails.get($.chatId);if(G)await this.seal(G);Y=await this.create($),z.rows.delete($.key),z.settled.delete($.key);try{let W;if(!await this.deps.deleteElementChecked(z.cardId,$.elementId,(K)=>{W=K})){let K=H3("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(z)}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(H){V.push(String(H))}if(V.length)throw Error(V.join("; "));return!0})}closeChat($){return U$($,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: ${k(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:!1};return this.attach(Y,$),this.tails.set($.chatId,Y),Y}async seal($,Z=!1){if($.sealed=!0,this.tails.get($.chatId)===$)this.tails.delete($.chatId);await this.settings($,!Z)}async settings($,Z=!0){this.deps.cancelSummary($.cardId);let J=$.settled.size===$.rows.size,Q={config:{streaming_mode:!J,summary:{content:TQ([...$.rows.values()])}}},Y=JSON.stringify(Q);if(Y!==$.settingsJson){let V;if($.pendingSettings=!0,!await this.deps.patchSettingsChecked($.cardId,Q,(X)=>{V=X}))throw H3("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 NW($){let{cardMessageId:Z,presentationErrors:J,promptArtifact:Q,...Y}=$;return{key:`run:${$.runId}`,chatId:$.chatId,elementId:s6($.runId),element:RQ($),summary:t6($),kind:"delegated",status:$.status,terminal:$.status==="completed"||$.status==="failed"||$.status==="cancelled",progressState:oU("sha256").update(JSON.stringify({...Y,workers:Y.workers.map(({steps:V,usage:X,durationMs:H,outputArtifact:z,...G})=>G)})).digest("hex"),attach:(V)=>{$.cardMessageId=V}}}function CQ($){return D4($.failure?.code,$.failure)}function tU($,Z){return $.status==="running"&&Z.status==="running"&&Object.keys({...$,...Z}).every((J)=>J==="steps"||J==="usage"||J==="lastToolName"||$[J]===Z[J])}function H3($,Z){return Error(`${$} MISS: ${k(Z.failure)}`)}var sU=50;var bQ=R(()=>{L$();Z1();t5();I()});function RW(){return new z3(kQ)}var kQ;var wQ=R(()=>{bQ();Z1();e();kQ={sendCard:i,getChatTailMessageId:hZ,convertMessageToCard:h$,recordCardCreated:A$,getElementCount:y9,addElementResult:M4,replaceElementResult:gz,deleteElementChecked:mz,cancelSummary:i0,patchSettingsChecked:C0,dispose:B$}});function rU(){return JSON.stringify([w5(),TX(),u0().map(($)=>[$.id,$.enabled,$.spawnRevision,$.usageAccount]),v.list().map(($)=>[$.id,$.name,$.revision])])}function yQ(){let $=rU();if(G3?.key===$)return G3.promise;let Z=["codex-sub","claude-sub","glm","dsh-glm","deepseek","deepseek-harness","openrouter","claude-native"],J=(H)=>Z.includes(H)?Z.indexOf(H):Z.length,Q=u0().filter((H)=>H.enabled||H.kind==="codex-subscription"&&v.list().some((z)=>z.id!=="default")).sort((H,z)=>J(H.id)-J(z.id)),Y=new Set,V=[];for(let H of Q){if(H.kind==="codex-subscription"){V.push(Q6().then((W)=>W.entries.filter((K)=>!K.duplicateOf).map((K)=>({id:`codex:${K.account.id}`,label:`Codex·${K.account.name}`,usage:_9(K.usage)}))));continue}let z=H.usageAccount?.id??sH(H.id);if(Y.has(z))continue;Y.add(z);let G=H.usageAccount?.label??(z==="glm"?"GLM Coding Plan":z==="deepseek"?"DeepSeek":H.kind==="claude-subscription"?"Claude 订阅":H.display);V.push(Promise.resolve().then(()=>H.readUsage()).catch((W)=>{let K=W instanceof Error?W.message:String(W);return B(`account usage ${z} MISS: ${K}`),{state:"network",windows:[],reason:K}}).then((W)=>[{id:z,label:G,usage:W}]))}let X=Promise.all(V).then((H)=>H.flat()).finally(()=>{if(G3?.promise===X)G3=void 0});return G3={key:$,promise:X},X}var G3;var TW=R(()=>{D0();GJ();U8();Q0();S9();M$();I()});function xW($){let Z=[];for(let J of $.matchAll(eU)){let Q=J[1]?.trim();if(Q)Z.push(Q)}return Z}function e6($,Z=process.platform){if(Z!=="win32")return $;let J=$O.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var eU,$O;var vQ=R(()=>{eU=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;$O=/^\/([a-zA-Z])\//});function CW($){if(EW.test($))return{marker:"start",body:$.replace(EW,"")};if(SW.test($))return{marker:"end",body:$.replace(SW,"")};return{marker:"none",body:$}}var EW,SW;var bW=R(()=>{EW=/^>{3,}[ \t]?/,SW=/^<{3,}[ \t]?/});async function kW($,Z,J,Q,Y){let{marker:V,body:X}=CW(Z);if(V==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)hQ($,"reopen");return $.multiMsgBuffer=[],fQ($,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}fQ($,X,J,Q,Y);let{multiMsgBuffer:H,multiMsgReactions:z}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await JO($,H,z),!0}if($.multiMsgBuffer!==null)return fQ($,Z,J,Q,Y),!0;return!1}function fQ($,Z,J,Q,Y){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Q,msgId:Y});if(Y)ZO($,Y)}function ZO($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await Q$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else g0(Z,J)})()}async function JO($,Z,J){for(let[X,H]of J)if(H)g0(X,H);let Q=Z.filter((X)=>X.text.trim()||X.files.length);if(Q.length===0){B(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await b($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Y=Q.map((X)=>{return(X.files.length?X.files.map((z)=>`[file: ${z}]`).join(" ")+`
238
238
  `:"")+X.text}).join(`
239
239
 
240
- `),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 hQ($,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);Q$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var wW=R(()=>{e();I();bW()});import{mkdtemp as YO,rm as VO,writeFile as XO}from"node:fs/promises";import{createRequire as HO}from"node:module";import{tmpdir as zO}from"node:os";import{join as yW}from"node:path";function LO($){let Z=IW.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:H}=F2("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Q(z);let G=Y.document("",{InputJax:new V({packages:X}),OutputJax:new H({fontCache:"none"})}),W={adaptor:z,doc:G};return IW.set($,W),W}function gW($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function PO($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function DO($,Z=mQ,J=!0){try{let Q=Z*GO,{adaptor:Y,doc:V}=LO(Z),X=V.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),H=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(H)){let n=H.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(n)}let z=H.indexOf("<svg"),G=H.lastIndexOf("</svg>");if(z<0||G<0)throw Error("MathJax returned no SVG");let W=H.slice(z,G+6),K=W.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let _=gW(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=gW(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),L=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!L)throw Error("MathJax SVG missing viewBox");let q=L.trim().split(/[\s,]+/).map(Number);if(q.length!==4||q.some((n)=>!Number.isFinite(n))||q[2]<=0||q[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,F,U,M]=q,O=/<text\b/.test(W)?jO:0,A=`${D} ${F} ${U+O} ${M}`,T=_*Q,y=O*(T/U),S=Math.max(1,Math.ceil(T+y)),h=Math.max(1,Math.ceil(j*Q)),l=WO-IQ*2,E=Math.min(1,l/S),m=Math.max(1,Math.round(S*E)),Y0=Math.max(1,Math.round(h*E));if(E<1&&Y0<KO)throw Error(`formula would be unreadable after width cap (${m}x${Y0})`);let w=m+IQ*2,N=Y0+fW*2,f=W.slice(K.length,-6).replace(/currentColor/g,vW).replace(/font-family="serif"/g,`font-family="${qO}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${N}" viewBox="0 0 ${w} ${N}" style="color:${vW}">`,`<rect x="0" y="0" width="${w}" height="${N}" rx="6" fill="${lW}"/>`,`<svg x="${IQ}" y="${fW}" width="${m}" height="${Y0}" viewBox="${PO(A)}" preserveAspectRatio="xMidYMid meet">`,f,"</svg>","</svg>"].join(""),width:w,height:N}}catch(Q){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function FO($,Z=mQ,J=!0){let Q=DO($,Z,J);if(!Q)return null;try{let{Resvg:Y}=F2("@resvg/resvg-js"),X=new Y(Q.svg,{background:lW,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:hW,sansSerifFamily:hW}}).render().asPng(),H=new DataView(X.buffer,X.byteOffset,X.byteLength),z=H.getUint32(16),G=H.getUint32(20);if(z!==Q.width||G!==Q.height)throw Error(`PNG dimensions ${z}x${G} != SVG ${Q.width}x${Q.height}`);return{png:X,width:z,height:G}}catch(Y){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function UO($){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 mW($,Z){let J=[],Q=(W,K,_)=>{let j=W[0],L=K.trim();if(!L)return;J.push({start:Z+W.index,end:Z+W.index+j.length,tex:L,raw:j,display:_})},Y,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Y=V.exec($))!==null)Q(Y,Y[1]??Y[2]??"",!0);let X=/\\\(([\s\S]+?)\\\)/g;while((Y=X.exec($))!==null)Q(Y,Y[1]??"",!1);let H=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=H.exec($))!==null){let W=(Y[1]??"").trim();if(UO(W))Q(Y,W,!1)}J.sort((W,K)=>W.start-K.start||K.end-W.end);let z=[],G=-1;for(let W of J){if(W.start<G)continue;z.push(W),G=W.end}return z}function uW($){let Z=VZ($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...mW($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...mW($.slice(Q),Q));return J}function MO($){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(pW[Q])return pW[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 RO($){let Z=cW.get($);if(Z!==void 0)return Z;return Z=AO++,cW.set($,Z),Z}function TO($,Z){return`${_O}\x00${RO(Z)}\x00${$}`}function xO($){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 EO($,Z){let J=TO($,Z),Q=D2.get(J);if(Q)return Q;let Y=gQ.get(J);if(Y)return Y;let V=(async()=>{let X=FO($,mQ,!0);if(!X)return null;let H=null;try{H=await YO(yW(zO(),"lodestar-math-"));let z=yW(H,`formula-${xO($)}.png`);await XO(z,X.png);let G=await Z(z,{tex:$,width:X.width,height:X.height});if(!G)return B(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let W={key:G,width:X.width,height:X.height};if(D2.has(J))D2.delete(J);D2.set(J,W);while(D2.size>NO){let K=D2.keys().next().value;if(typeof K!=="string")break;D2.delete(K)}return W}catch(z){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(H)try{await VO(H,{recursive:!0,force:!0})}catch(z){B(`math-render: temp cleanup failed for ${H}: ${z}`)}}})();gQ.set(J,V);try{return await V}finally{gQ.delete(J)}}function SO($,Z,J){let Q=$.width<=BO;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 dW($,Z={}){let J=uW($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??OO,Y=await Promise.all(J.map(async(W)=>{if(!W.display){let K=MO(W.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await EO(W.tex,Q)}})),V=[],X="",H=0,z=0,G=()=>{if(!X)return;if(X.trim())V.push({type:"markdown",text:X});X=""};for(let W=0;W<J.length;W++){let K=J[W],_=Y[W];if(X+=$.slice(H,K.start),_.unicode!==null){X+=_.unicode,H=K.end;continue}let j=_.uploaded;if(!j){X+=K.raw,H=K.end;continue}G(),V.push(SO(j,K,z++)),H=K.end}if(X+=$.slice(H),G(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function pQ($){return uW($).length>0}var F2,GO=0.5,mQ=22,vW="#1F2329",lW="#F7F8FA",IQ=12,fW=8,WO=720,KO=14,BO=278,_O="v4-native-cjk-tail-pad",jO=1100,hW,qO="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",IW,pW,OO=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (e(),J0));return Z($)},cW,AO=1,D2,gQ,NO=512;var iW=R(()=>{I();F2=HO(import.meta.url),hW=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",IW=new Map;pW={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:"Ω"};cW=new WeakMap,D2=new Map,gQ=new Map});import{readFileSync as bO}from"node:fs";function E4($){return cQ.has($)}function K3($){cQ.add($)}function B3($){cQ.delete($)}function w1(){try{let $={};for(let[Z,J]of m0)$[Z]=J;o(W3,$)}catch($){throw B(`notify-callbacks: save failed (${W3}): ${$}`),$}}function sW(){let $=[],Z;try{Z=bO(W3,"utf8")}catch(J){if(J?.code==="ENOENT")return[];throw B(`notify-callbacks: read failed (${W3}): ${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()-oW,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)w1()}catch(J){throw B(`notify-callbacks: load failed (${W3}): ${J}`),J}return $}function tW($){let Z=Date.now();if(Z-aW>=kO)wO(Z),aW=Z;m0.set($.notifyId,$),w1()}function Y1($){return m0.get($)}function rW($,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{w1()}catch(Y){throw delete Q.dispatchState,Y}}function eW($){let Z=m0.get($);if(!Z?.dispatchState)throw Error(`notify callback is not dispatching: ${$}`);let J=Z.dispatchState;delete Z.dispatchState;try{return w1(),{state:"retry"}}catch(Q){Z.dispatchState=J;let Y=`callback failure persistence failed: ${Q instanceof Error?Q.message:Q}`;try{$7($,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 lQ($){return[...m0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function _3($,Z){if(!$)return;return lQ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function $K($,Z){return!!Z&&[...m0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function S4($,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{w1()}catch(V){if(Q)J.replyState=Q;else delete J.replyState;if(Y)J.replyMessageIds=Y;else delete J.replyMessageIds;throw V}}function j3($,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{w1()}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 $7($,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,w1()}function Z7($,Z,J){try{return j3($,Z,J),{state:"complete"}}catch(Q){let V=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{$7($,Z,J,V)}catch(X){let H=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${H}`;let z=m0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function wO($=Date.now()){let Z=$-oW,J=0;for(let[Q,Y]of m0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)m0.delete(Q),J++;if(J>0)w1();return J}async function uQ($,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(),nW);try{let X=await VV($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let z;try{let G=(await X.text()).trim();if(G.startsWith("{")){let W=JSON.parse(G),K=typeof W?.text==="string"?W.text:typeof W?.reply==="string"?W.reply:typeof W?.message==="string"?W.message:"";if(K.trim())z=K.trim().slice(0,500)}else if(G)z=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:z}}let H="";try{H=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${H?` ${H}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${nW}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function ZK($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((H)=>H.id===Q):void 0,V=$.replyState?.response,X=Q!==void 0?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q}}:V?{response:{type:"text",...V}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Q===void 0?"resolved":J&&Q===void 0?"unknown":$.replyState.status,prompt_message_id:$.replyState.promptMessageId,operator:{open_id:$.replyState.openId},...$.replyState.cancelReason?{cancel_reason:$.replyState.cancelReason}:{},...$.replyState.error?{error:$.replyState.error}:{}}}:{},...Z?{...X,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...X,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var oW=604800000,nW=2500,m0,aW,kO=86400000,cQ,W3;var q3=R(()=>{o0();I();V0();v0();m0=new Map,aW=Date.now(),cQ=new Set;W3=nY});function J7($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function C4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(_3($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(J7($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function dQ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Q=J.currentIdx===void 0?void 0:_3($.chatId)?"notification":J7($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Q}}function iQ($,Z){let J=$.pendingAsks.get(Z),Q=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||C4($,Z)||!Q?.userOpenId||!Q.messageId)return;J.announced=!0;let Y=(J.announcementVersion??0)+1;J.announcementVersion=Y;let V=J.questions[J.currentIdx]?.question.trim()??"",X=V.length>40?V.slice(0,40)+"…":V,H=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(i0(Q.cardId),await z6(Q.cardId,{config:{summary:{content:H}}}),$.currentTurn!==Q||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Y||J.currentIdx===void 0||C4($,Z))return;await e1(Q.messageId,[Q.userOpenId])})().catch((z)=>B(`session "${$.sessionName}": question notification failed: ${z}`))}function Q7($){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=dQ($,J);if(V.waitingFor)Q.announced=!1,Q.announcementVersion=(Q.announcementVersion??0)+1;P0(Z.cardId,C.tool(Y.i),R4(Y.i,J,Q.questions,"\uD83E\uDD14",V)),iQ($,J)}}function JK($){return J7($)!==void 0}async function QK($,Z,J,Q){let Y=J7($);if(!Y){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Q);return}let[V,X]=Y,H=C4($,V);if(H){let G=`${H}。这条文字未提交,请稍后重新发送。`,W;if(!await b($.chatId,G,(K)=>{W=K}))throw Error(`提问等待提示发送失败: ${G}
241
- ${k(W)}`);return}if(await nQ($,V,X.currentIdx,Z,J)&&Q)Q$(Q,"CheckMark")}async function YK($,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 VK($,Z,{optionIdx:Q,user:Y})}async function nQ($,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 VK($,Z,{customText:X,user:Y})}function VK($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=C4($,Z);if(Y)return B(`session "${$.sessionName}": ask ${Z} waiting: ${Y}`),!1;let V=Q.currentIdx,X=Q.questions[V];if(!X)return B(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let H;if(J.customText!==void 0)H=J.customText;else if(J.optionIdx!==void 0){let _=X.options?.[J.optionIdx];if(!_)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;H=_.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[X.question]=H,Q.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Q.questions.length,G=void 0;for(let _=V+1;_<z;_++)if(!Q.answered.has(_)){G=_;break}Q.currentIdx=G;let W=$.currentTurn,K=W?.toolByUseId.get(Z);if(W&&K){let _=R4(K.i,Z,Q.questions,G===void 0?"✅":"\uD83E\uDD14",{currentIdx:G,answered:Q.answered});P0(W.cardId,C.tool(K.i),_)}if(G===void 0)if(Q.requestId)aQ($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),Q7($);return!0}function aQ($,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),Q7($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var Y7=R(()=>{Z1();L$();e();I();q3()});import{isAbsolute as vO}from"node:path";function k0($){if($?.planLiveInserted)return C.planLive;return $?.taskLiveInserted?C.taskBoardLive:C.footer}function fO($){return $==="ImageGeneration"||$==="imageGeneration"}function hO($,Z,J){if(J||!fO($))return null;let Q=e6(Z.trim());return vO(Q)?Q:null}function IO($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function XK($,Z,J){return $==="read"?r9(Z,J):t9(Z,J)}function HK($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=IO(J);if(Y&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(z);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:z,name:J,input:Q,batchSlot:W});let K=Y==="read"?r9(z,G.items):t9(z,G.items);P0($.currentTurn.cardId,C.tool(z),K),V7($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let V=L2(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,N0(z.cardId,P2($.taskBoard),{type:"insert_before",targetElementId:C.footer});else K0(z.cardId,C.taskBoardLive,P2($.taskBoard),{notifyCardFailure:!1});let G=V==="TaskCreate";if(G)z.taskUpdateI=null;else z.taskCreateI=null;let W=(G?z.taskCreateI:z.taskUpdateI)===null;if(W)if(G)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let K=G?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:K,name:J,input:Q});let _=k1(K,$.taskBoard,{name:V,status:"⏳"});W?N0(z.cardId,_,{type:"insert_before",targetElementId:k0(z)}):P0(z.cardId,C.tool(K),_),V7(z,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let z=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:z}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let G=Y==="read"?r9(X,z):t9(X,z);N0($.currentTurn.cardId,G,{type:"insert_before",targetElementId:k0($.currentTurn)},void 0,"capacity"),V7($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let z=Array.isArray(Q?.questions)?Q.questions:[],G=z.length>0?0:void 0,W=new Map;$.pendingAsks.set(Z,{questions:z,i:X,answers:{},answered:W,currentIdx:G});let K=R4(X,Z,z,"\uD83E\uDD14",dQ($,Z));N0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:k0($.currentTurn)}),iQ($,Z);return}let H=p$(X,J,Q,null,"⏳");N0($.currentTurn.cardId,H,{type:"insert_before",targetElementId:k0($.currentTurn)},void 0,"capacity"),V7($.currentTurn,J,Q)}function V7($,Z,J){if(!$)return;let Q=x1(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,V=K2(Z),X=Y?`\uD83D\uDD27 ${V}: ${Y}`:`\uD83D\uDD27 ${V}`;M4($.cardId,X)}function zK($,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(`
242
- `):JSON.stringify(J);if(V.output=X,V.isError=Q,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=hO(V.name,X,Q);if(H){gO($,$.currentTurn,V,H),U2($);return}if(V.name==="AskUserQuestion"){U2($);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 _=XK(W.kind,V.i,W.items);P0($.currentTurn.cardId,C.tool(V.i),_)}U2($);return}let z=L2(V.name);if(z){mO($,V,z,V.input,X,Q,V.resolvedNote);return}let G=p$(V.i,V.name,V.input,X,Q?"❌":"✅",V.resolvedNote);P0($.currentTurn.cardId,C.tool(V.i),G),U2($)}function gO($,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,H=X.get(Y)??new Set;X.set(Y,H);let z=[],G=(async()=>{let W=null;try{W=await IZ(Q,(q)=>{z.push(`图片上传:${k(q)}`)})}catch(q){z.push(`图片上传:${k(q)}`),B(`generated image upload failed: ${q}`)}if(W){let q=!1;try{q=await K0(Y,V,p$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1,onFailure:(D)=>{z.push(`图片嵌入:${k(D)}`)}})}catch(D){z.push(`图片嵌入:${k(D)}`),B(`generated image embed failed: ${D}`)}if(q){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,_=W?await p8($.chatId,W,(q)=>{K=q})!==null:await R9($.chatId,Q);if(_)Z.outboundSentPaths.add(Q);else B(`generated image delivery failed: ${Q}`);if(!_&&W)z.push(`图片发送:${k(K)}`);J.resolvedNote=[_?"图片已单独发送。":"图片发送失败。",...z].join(`
240
+ `),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 hQ($,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);Q$(Q,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var wW=R(()=>{e();I();bW()});import{mkdtemp as YO,rm as VO,writeFile as XO}from"node:fs/promises";import{createRequire as HO}from"node:module";import{tmpdir as zO}from"node:os";import{join as yW}from"node:path";function LO($){let Z=IW.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:H}=F2("mathjax-full/js/output/svg.js"),z=J({fontSize:$});Q(z);let G=Y.document("",{InputJax:new V({packages:X}),OutputJax:new H({fontCache:"none"})}),W={adaptor:z,doc:G};return IW.set($,W),W}function gW($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function PO($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function DO($,Z=mQ,J=!0){try{let Q=Z*GO,{adaptor:Y,doc:V}=LO(Z),X=V.convert($,{display:J,em:Z,ex:Q,containerWidth:80*Z}),H=Y.outerHTML(X);if(/data-mjx-error=|mjx-merror/.test(H)){let n=H.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(n)}let z=H.indexOf("<svg"),G=H.lastIndexOf("</svg>");if(z<0||G<0)throw Error("MathJax returned no SVG");let W=H.slice(z,G+6),K=W.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let _=gW(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),j=gW(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),L=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!L)throw Error("MathJax SVG missing viewBox");let q=L.trim().split(/[\s,]+/).map(Number);if(q.length!==4||q.some((n)=>!Number.isFinite(n))||q[2]<=0||q[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,F,M,U]=q,O=/<text\b/.test(W)?jO:0,A=`${D} ${F} ${M+O} ${U}`,T=_*Q,y=O*(T/M),S=Math.max(1,Math.ceil(T+y)),h=Math.max(1,Math.ceil(j*Q)),l=WO-IQ*2,E=Math.min(1,l/S),m=Math.max(1,Math.round(S*E)),Y0=Math.max(1,Math.round(h*E));if(E<1&&Y0<KO)throw Error(`formula would be unreadable after width cap (${m}x${Y0})`);let w=m+IQ*2,N=Y0+fW*2,f=W.slice(K.length,-6).replace(/currentColor/g,vW).replace(/font-family="serif"/g,`font-family="${qO}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${N}" viewBox="0 0 ${w} ${N}" style="color:${vW}">`,`<rect x="0" y="0" width="${w}" height="${N}" rx="6" fill="${lW}"/>`,`<svg x="${IQ}" y="${fW}" width="${m}" height="${Y0}" viewBox="${PO(A)}" preserveAspectRatio="xMidYMid meet">`,f,"</svg>","</svg>"].join(""),width:w,height:N}}catch(Q){return B(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Q}`),null}}function FO($,Z=mQ,J=!0){let Q=DO($,Z,J);if(!Q)return null;try{let{Resvg:Y}=F2("@resvg/resvg-js"),X=new Y(Q.svg,{background:lW,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:hW,sansSerifFamily:hW}}).render().asPng(),H=new DataView(X.buffer,X.byteOffset,X.byteLength),z=H.getUint32(16),G=H.getUint32(20);if(z!==Q.width||G!==Q.height)throw Error(`PNG dimensions ${z}x${G} != SVG ${Q.width}x${Q.height}`);return{png:X,width:z,height:G}}catch(Y){return B(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Y}`),null}}function MO($){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 mW($,Z){let J=[],Q=(W,K,_)=>{let j=W[0],L=K.trim();if(!L)return;J.push({start:Z+W.index,end:Z+W.index+j.length,tex:L,raw:j,display:_})},Y,V=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Y=V.exec($))!==null)Q(Y,Y[1]??Y[2]??"",!0);let X=/\\\(([\s\S]+?)\\\)/g;while((Y=X.exec($))!==null)Q(Y,Y[1]??"",!1);let H=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Y=H.exec($))!==null){let W=(Y[1]??"").trim();if(MO(W))Q(Y,W,!1)}J.sort((W,K)=>W.start-K.start||K.end-W.end);let z=[],G=-1;for(let W of J){if(W.start<G)continue;z.push(W),G=W.end}return z}function uW($){let Z=VZ($),J=[],Q=0;for(let Y of Z){if(Q<Y.start)J.push(...mW($.slice(Q,Y.start),Q));Q=Math.max(Q,Y.end)}if(Q<$.length)J.push(...mW($.slice(Q),Q));return J}function UO($){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(pW[Q])return pW[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 RO($){let Z=cW.get($);if(Z!==void 0)return Z;return Z=AO++,cW.set($,Z),Z}function TO($,Z){return`${_O}\x00${RO(Z)}\x00${$}`}function xO($){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 EO($,Z){let J=TO($,Z),Q=D2.get(J);if(Q)return Q;let Y=gQ.get(J);if(Y)return Y;let V=(async()=>{let X=FO($,mQ,!0);if(!X)return null;let H=null;try{H=await YO(yW(zO(),"lodestar-math-"));let z=yW(H,`formula-${xO($)}.png`);await XO(z,X.png);let G=await Z(z,{tex:$,width:X.width,height:X.height});if(!G)return B(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let W={key:G,width:X.width,height:X.height};if(D2.has(J))D2.delete(J);D2.set(J,W);while(D2.size>NO){let K=D2.keys().next().value;if(typeof K!=="string")break;D2.delete(K)}return W}catch(z){return B(`math-render: upload failed for ${$.slice(0,80)}…: ${z}`),null}finally{if(H)try{await VO(H,{recursive:!0,force:!0})}catch(z){B(`math-render: temp cleanup failed for ${H}: ${z}`)}}})();gQ.set(J,V);try{return await V}finally{gQ.delete(J)}}function SO($,Z,J){let Q=$.width<=BO;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 dW($,Z={}){let J=uW($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Q=Z.uploader??OO,Y=await Promise.all(J.map(async(W)=>{if(!W.display){let K=UO(W.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await EO(W.tex,Q)}})),V=[],X="",H=0,z=0,G=()=>{if(!X)return;if(X.trim())V.push({type:"markdown",text:X});X=""};for(let W=0;W<J.length;W++){let K=J[W],_=Y[W];if(X+=$.slice(H,K.start),_.unicode!==null){X+=_.unicode,H=K.end;continue}let j=_.uploaded;if(!j){X+=K.raw,H=K.end;continue}G(),V.push(SO(j,K,z++)),H=K.end}if(X+=$.slice(H),G(),!V.length)V.push({type:"markdown",text:$});return{blocks:V,formulaCount:J.length,renderedImageCount:z}}function pQ($){return uW($).length>0}var F2,GO=0.5,mQ=22,vW="#1F2329",lW="#F7F8FA",IQ=12,fW=8,WO=720,KO=14,BO=278,_O="v4-native-cjk-tail-pad",jO=1100,hW,qO="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",IW,pW,OO=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (e(),J0));return Z($)},cW,AO=1,D2,gQ,NO=512;var iW=R(()=>{I();F2=HO(import.meta.url),hW=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",IW=new Map;pW={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:"Ω"};cW=new WeakMap,D2=new Map,gQ=new Map});import{readFileSync as bO}from"node:fs";function E4($){return cQ.has($)}function K3($){cQ.add($)}function B3($){cQ.delete($)}function w1(){try{let $={};for(let[Z,J]of m0)$[Z]=J;o(W3,$)}catch($){throw B(`notify-callbacks: save failed (${W3}): ${$}`),$}}function sW(){let $=[],Z;try{Z=bO(W3,"utf8")}catch(J){if(J?.code==="ENOENT")return[];throw B(`notify-callbacks: read failed (${W3}): ${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()-oW,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)w1()}catch(J){throw B(`notify-callbacks: load failed (${W3}): ${J}`),J}return $}function tW($){let Z=Date.now();if(Z-aW>=kO)wO(Z),aW=Z;m0.set($.notifyId,$),w1()}function Y1($){return m0.get($)}function rW($,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{w1()}catch(Y){throw delete Q.dispatchState,Y}}function eW($){let Z=m0.get($);if(!Z?.dispatchState)throw Error(`notify callback is not dispatching: ${$}`);let J=Z.dispatchState;delete Z.dispatchState;try{return w1(),{state:"retry"}}catch(Q){Z.dispatchState=J;let Y=`callback failure persistence failed: ${Q instanceof Error?Q.message:Q}`;try{$7($,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 lQ($){return[...m0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function _3($,Z){if(!$)return;return lQ($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function $K($,Z){return!!Z&&[...m0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function S4($,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{w1()}catch(V){if(Q)J.replyState=Q;else delete J.replyState;if(Y)J.replyMessageIds=Y;else delete J.replyMessageIds;throw V}}function j3($,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{w1()}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 $7($,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,w1()}function Z7($,Z,J){try{return j3($,Z,J),{state:"complete"}}catch(Q){let V=`resolved tombstone persistence failed: ${Q instanceof Error?Q.message:String(Q)}`;try{$7($,Z,J,V)}catch(X){let H=X instanceof Error?X.message:String(X);V+=`; unknown tombstone persistence also failed: ${H}`;let z=m0.get($);if(z)z.unknownReason=V}return{state:"unknown",detail:V}}}function wO($=Date.now()){let Z=$-oW,J=0;for(let[Q,Y]of m0)if(typeof Y.createdAt!=="number"||Y.createdAt<Z)m0.delete(Q),J++;if(J>0)w1();return J}async function uQ($,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(),nW);try{let X=await VV($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Q),signal:Y.signal});if(X.status>=200&&X.status<300){let z;try{let G=(await X.text()).trim();if(G.startsWith("{")){let W=JSON.parse(G),K=typeof W?.text==="string"?W.text:typeof W?.reply==="string"?W.reply:typeof W?.message==="string"?W.message:"";if(K.trim())z=K.trim().slice(0,500)}else if(G)z=G.slice(0,500)}catch{}return{ok:!0,detail:`${X.status}`,reply:z}}let H="";try{H=(await X.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${X.status}${H?` ${H}`:""}`}}catch(X){if(X?.name==="AbortError")return{ok:!1,detail:`回调超时 ${nW}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(X?.message??X).slice(0,160)}`}}finally{clearTimeout(V)}}function ZK($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Q=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Y=Q?$.buttons.find((H)=>H.id===Q):void 0,V=$.replyState?.response,X=Q!==void 0?{button:Y?{id:Y.id,text:Y.text,type:Y.type}:{id:Q}}:V?{response:{type:"text",...V}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Q===void 0?"resolved":J&&Q===void 0?"unknown":$.replyState.status,prompt_message_id:$.replyState.promptMessageId,operator:{open_id:$.replyState.openId},...$.replyState.cancelReason?{cancel_reason:$.replyState.cancelReason}:{},...$.replyState.error?{error:$.replyState.error}:{}}}:{},...Z?{...X,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...X,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var oW=604800000,nW=2500,m0,aW,kO=86400000,cQ,W3;var q3=R(()=>{o0();I();V0();v0();m0=new Map,aW=Date.now(),cQ=new Set;W3=nY});function J7($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function C4($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(_3($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(J7($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function dQ($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Q=J.currentIdx===void 0?void 0:_3($.chatId)?"notification":J7($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Q}}function iQ($,Z){let J=$.pendingAsks.get(Z),Q=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||C4($,Z)||!Q?.userOpenId||!Q.messageId)return;J.announced=!0;let Y=(J.announcementVersion??0)+1;J.announcementVersion=Y;let V=J.questions[J.currentIdx]?.question.trim()??"",X=V.length>40?V.slice(0,40)+"…":V,H=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${X?`: ${X}`:""}`:X?`❓ ${X}`:"❓ 等你回答问题";(async()=>{if(i0(Q.cardId),await z6(Q.cardId,{config:{summary:{content:H}}}),$.currentTurn!==Q||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Y||J.currentIdx===void 0||C4($,Z))return;await e1(Q.messageId,[Q.userOpenId])})().catch((z)=>B(`session "${$.sessionName}": question notification failed: ${z}`))}function Q7($){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=dQ($,J);if(V.waitingFor)Q.announced=!1,Q.announcementVersion=(Q.announcementVersion??0)+1;P0(Z.cardId,C.tool(Y.i),R4(Y.i,J,Q.questions,"\uD83E\uDD14",V)),iQ($,J)}}function JK($){return J7($)!==void 0}async function QK($,Z,J,Q){let Y=J7($);if(!Y){B(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Q);return}let[V,X]=Y,H=C4($,V);if(H){let G=`${H}。这条文字未提交,请稍后重新发送。`,W;if(!await b($.chatId,G,(K)=>{W=K}))throw Error(`提问等待提示发送失败: ${G}
241
+ ${k(W)}`);return}if(await nQ($,V,X.currentIdx,Z,J)&&Q)Q$(Q,"CheckMark")}async function YK($,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 VK($,Z,{optionIdx:Q,user:Y})}async function nQ($,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 VK($,Z,{customText:X,user:Y})}function VK($,Z,J){let Q=$.pendingAsks.get(Z);if(!Q||Q.currentIdx===void 0)return!1;let Y=C4($,Z);if(Y)return B(`session "${$.sessionName}": ask ${Z} waiting: ${Y}`),!1;let V=Q.currentIdx,X=Q.questions[V];if(!X)return B(`session "${$.sessionName}": advanceAsk currentIdx=${V} out of range`),!1;let H;if(J.customText!==void 0)H=J.customText;else if(J.optionIdx!==void 0){let _=X.options?.[J.optionIdx];if(!_)return B(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;H=_.label}else return B(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Q.answers[X.question]=H,Q.answered.set(V,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let z=Q.questions.length,G=void 0;for(let _=V+1;_<z;_++)if(!Q.answered.has(_)){G=_;break}Q.currentIdx=G;let W=$.currentTurn,K=W?.toolByUseId.get(Z);if(W&&K){let _=R4(K.i,Z,Q.questions,G===void 0?"✅":"\uD83E\uDD14",{currentIdx:G,answered:Q.answered});P0(W.cardId,C.tool(K.i),_)}if(G===void 0)if(Q.requestId)aQ($,Z);else B(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),Q7($);return!0}function aQ($,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),Q7($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var Y7=R(()=>{Z1();L$();e();I();q3()});import{isAbsolute as vO}from"node:path";function k0($){if($?.planLiveInserted)return C.planLive;return $?.taskLiveInserted?C.taskBoardLive:C.footer}function fO($){return $==="ImageGeneration"||$==="imageGeneration"}function hO($,Z,J){if(J||!fO($))return null;let Q=e6(Z.trim());return vO(Q)?Q:null}function IO($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function XK($,Z,J){return $==="read"?r9(Z,J):t9(Z,J)}function HK($,Z,J,Q){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Y=IO(J);if(Y&&$.currentTurn.openBatchI!==null){let z=$.currentTurn.openBatchI,G=$.currentTurn.toolBatches.get(z);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:z,name:J,input:Q,batchSlot:W});let K=Y==="read"?r9(z,G.items):t9(z,G.items);P0($.currentTurn.cardId,C.tool(z),K),V7($.currentTurn,J,Q);return}}if(!Y)$.currentTurn.openBatchI=null;let V=L2(J);if(V){let z=$.currentTurn;if(V==="TaskCreate"&&!z.taskBoardResetThisTurn)$.taskBoard=[],z.taskBoardResetThisTurn=!0;if(!z.taskLiveInserted)z.taskLiveInserted=!0,N0(z.cardId,P2($.taskBoard),{type:"insert_before",targetElementId:C.footer});else K0(z.cardId,C.taskBoardLive,P2($.taskBoard),{notifyCardFailure:!1});let G=V==="TaskCreate";if(G)z.taskUpdateI=null;else z.taskCreateI=null;let W=(G?z.taskCreateI:z.taskUpdateI)===null;if(W)if(G)z.taskCreateI=z.toolCount++;else z.taskUpdateI=z.toolCount++;let K=G?z.taskCreateI:z.taskUpdateI;z.toolByUseId.set(Z,{i:K,name:J,input:Q});let _=k1(K,$.taskBoard,{name:V,status:"⏳"});W?N0(z.cardId,_,{type:"insert_before",targetElementId:k0(z)}):P0(z.cardId,C.tool(K),_),V7(z,J,Q);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let X=$.currentTurn.toolCount++;if(Y){$.currentTurn.openBatchI=X;let z=[{toolUseId:Z,input:Q,output:null,isError:!1}];$.currentTurn.toolBatches.set(X,{kind:Y,items:z}),$.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q,batchSlot:0});let G=Y==="read"?r9(X,z):t9(X,z);N0($.currentTurn.cardId,G,{type:"insert_before",targetElementId:k0($.currentTurn)},void 0,"capacity"),V7($.currentTurn,J,Q);return}if($.currentTurn.toolByUseId.set(Z,{i:X,name:J,input:Q}),J==="AskUserQuestion"){let z=Array.isArray(Q?.questions)?Q.questions:[],G=z.length>0?0:void 0,W=new Map;$.pendingAsks.set(Z,{questions:z,i:X,answers:{},answered:W,currentIdx:G});let K=R4(X,Z,z,"\uD83E\uDD14",dQ($,Z));N0($.currentTurn.cardId,K,{type:"insert_before",targetElementId:k0($.currentTurn)}),iQ($,Z);return}let H=p$(X,J,Q,null,"⏳");N0($.currentTurn.cardId,H,{type:"insert_before",targetElementId:k0($.currentTurn)},void 0,"capacity"),V7($.currentTurn,J,Q)}function V7($,Z,J){if(!$)return;let Q=x1(Z,J),Y=Q.length>80?Q.slice(0,80)+"…":Q,V=K2(Z),X=Y?`\uD83D\uDD27 ${V}: ${Y}`:`\uD83D\uDD27 ${V}`;U4($.cardId,X)}function zK($,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(`
242
+ `):JSON.stringify(J);if(V.output=X,V.isError=Q,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=hO(V.name,X,Q);if(H){gO($,$.currentTurn,V,H),M2($);return}if(V.name==="AskUserQuestion"){M2($);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 _=XK(W.kind,V.i,W.items);P0($.currentTurn.cardId,C.tool(V.i),_)}M2($);return}let z=L2(V.name);if(z){mO($,V,z,V.input,X,Q,V.resolvedNote);return}let G=p$(V.i,V.name,V.input,X,Q?"❌":"✅",V.resolvedNote);P0($.currentTurn.cardId,C.tool(V.i),G),M2($)}function gO($,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,H=X.get(Y)??new Set;X.set(Y,H);let z=[],G=(async()=>{let W=null;try{W=await IZ(Q,(q)=>{z.push(`图片上传:${k(q)}`)})}catch(q){z.push(`图片上传:${k(q)}`),B(`generated image upload failed: ${q}`)}if(W){let q=!1;try{q=await K0(Y,V,p$(J.i,J.name,J.input,J.output??null,"✅",J.resolvedNote,W),{notifyCardFailure:!1,onFailure:(D)=>{z.push(`图片嵌入:${k(D)}`)}})}catch(D){z.push(`图片嵌入:${k(D)}`),B(`generated image embed failed: ${D}`)}if(q){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,_=W?await p8($.chatId,W,(q)=>{K=q})!==null:await R9($.chatId,Q);if(_)Z.outboundSentPaths.add(Q);else B(`generated image delivery failed: ${Q}`);if(!_&&W)z.push(`图片发送:${k(K)}`);J.resolvedNote=[_?"图片已单独发送。":"图片发送失败。",...z].join(`
243
243
  `);let j,L=!1;try{L=await K0(Y,V,p$(J.i,J.name,J.input,J.output??null,_?"✅":"❌",J.resolvedNote),{notifyCardFailure:!1,onFailure:(q)=>{j=q}})}catch(q){j=q}if(!L)B(`generated image status write failed card=${Y} path=${Q}: ${k(j)}
244
244
  ${J.resolvedNote}`);if(!_&&W)await b($.chatId,`❌ 生成图片发送失败:${z.join(`
245
245
  `)}`)})().catch(async(W)=>{B(`generated image delivery failed: ${W}`),await b($.chatId,`❌ 生成图片发送失败:${[...new Set([...z,k(W)])].join(`
246
- `)}`)});H.add(G),G.finally(()=>{if(H.delete(G),!H.size)X.delete(Y)}).catch((W)=>B(`generated image failure notice failed: ${W}`))}async function oQ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Q)=>[...Q]);await Promise.allSettled(J)}function mO($,Z,J,Q,Y,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=EQ($.taskBoard,J,Q,Y);let H=k1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(P0($.currentTurn.cardId,C.tool(Z.i),H),$.currentTurn.taskLiveInserted)K0($.currentTurn.cardId,C.taskBoardLive,P2($.taskBoard),{notifyCardFailure:!1});U2($)}function U2($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function sQ($,Z,J,Q,Y,V=$.currentTurn){let X=V;if(!X)return;for(let[H,z]of Q){if(X.toolByUseId.has(H))continue;let G=z.batchSlot??null,W=z.input,K,_;if(G!=null){let U=Y.get(z.i)?.items[G];if(!U)continue;W=U.input,K=U.output,_=U.isError}else K=z.output??null,_=z.isError??!1;let j=K!=null,L=F4(Z,C.tool(z.i));if(j&&!L)continue;if(G!=null){let U=Y.get(z.i)?.kind;if(!U)continue;let M=X.toolCount++,O={toolUseId:H,input:W,output:K,isError:_};X.toolBatches.set(M,{kind:U,items:[O]}),X.toolByUseId.set(H,{...z,i:M,batchSlot:0}),N0(J,XK(U,M,[O]),{type:"insert_before",targetElementId:k0(X)});continue}let q=L2(z.name);if(q){let U=q==="TaskCreate";if(U)X.taskUpdateI=null;else X.taskCreateI=null;let M=(U?X.taskCreateI:X.taskUpdateI)===null;if(M)if(U)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let O=U?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(H,{...z,i:O});let A=!j?"⏳":_?"❌":"✅",T=k1(O,$.taskBoard,{name:q,status:A},z.resolvedNote);M?N0(J,T,{type:"insert_before",targetElementId:k0(X)}):P0(J,C.tool(O),T);continue}let D=X.toolCount++;X.toolByUseId.set(H,{...z,i:D});let F=!j?"⏳":_?"❌":"✅";N0(J,p$(D,z.name,z.input,K,F,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:k0(X)})}}var GK=R(()=>{vQ();Z1();L$();e();I();Y7()});async function WK($,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 H=$.currentTurn,z=H?.toolByUseId.get(Y.toolUseId);if(H&&z){let G=L2(z.name);if(J==="deny"){let W=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,K=G?k1(z.i,$.taskBoard,{name:G,status:"❌"},W):p$(z.i,z.name,z.input,W,"❌");P0(H.cardId,C.tool(z.i),K)}else{let W=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${W}** by ${Q||"匿名"}`;let K=G?k1(z.i,$.taskBoard,{name:G,status:"⏳"},z.resolvedNote):p$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);P0(H.cardId,C.tool(z.i),K)}}if(B(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Y.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function KK($,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)aQ($,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=QQ(Y.i,Y.name,Y.input,Z.request_id);if(P0(J.cardId,C.tool(Y.i),V),J.userOpenId&&J.messageId){let X=x1(Y.name,Y.input),H=K2(Y.name),z=X&&X.length>30?X.slice(0,30)+"…":X,G=z?`\uD83D\uDD10 等审批: ${H} · ${z}`:`\uD83D\uDD10 等审批: ${H}`;(async()=>{i0(J.cardId),await z6(J.cardId,{config:{summary:{content:G}}}),await e1(J.messageId,[J.userOpenId])})()}}var BK=R(()=>{Z1();L$();e();I();Y7()});function uO($){let Z=!1,J=()=>{},Q=()=>{},Y=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",G),$.off("error",W)},X=(_)=>{if(Z)return;Z=!0,V(),J(_)},H=(_)=>{if(Z)return;Z=!0,V(),Q(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Y&&_.threadId!==Y)return;X(_)},G=()=>H(Error(`${$.provider} process exited before context compaction completed`)),W=(_)=>H(_ instanceof Error?_:Error(String(_))),K=new Promise((_,j)=>{J=_,Q=j});return $.on("context_compacted",z),$.once("exit",G),$.once("error",W),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function dO($,Z){let J=[],Q=new Set,Y=(H,z)=>{let G=z.threadId??Z;if(G&&H.threadId&&H.threadId!==G)return!1;if(z.turnId)return H.turnId===z.turnId;return!0},V=(H)=>{for(let z=J.length-1;z>=0;z--){let G=J[z];if(G&&Y(G,H))return G}return null},X=(H)=>{if(Z&&H.threadId&&H.threadId!==Z)return;let z={usage:H.usage,contextWindow:H.contextWindow,threadId:H.threadId,turnId:H.turnId};J.push(z);for(let G of[...Q])if(Y(z,G.notice))G.finish(z)};return $.on("token_usage",X),{waitFor(H,z){let G=V(H);if(G)return Promise.resolve(G);return new Promise((W)=>{let K=null,_={notice:H,finish:(j)=>{if(K)clearTimeout(K);Q.delete(_),W(j)}};K=setTimeout(()=>_.finish(null),z),Q.add(_)})},cancel(){$.off("token_usage",X);for(let H of[...Q])H.finish(null)}}}function iO($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=M6($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=O6($.contextWindow);return` · \uD83E\uDDE0 ${DG(Z,J)} (${A6(Z,J)})`}async function _K($){$.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?x0(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)},H=uO(J),z=dO(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let G=await H.promise,W=await z.waitFor(G,lO),K=G.threadId?` thread=${x0(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${iO(W)}`))}catch(G){if(H.cancel(),G instanceof l1)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${x(G)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var lO=1500;var jK=R(()=>{B0();e()});import{randomUUID as aO}from"node:crypto";function qK($,Z){return{ok:!1,message:Z,card:u6($.sessionName,!1,Z)}}async function rQ($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return qK($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${x(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof p2&&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}`),qK($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${c0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:Q3({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:ZY($,Z.provider)})}}async function oO($,Z,J,Q,Y,V,X){let H,z=new Promise((L)=>{H=L}),G={proc:Z,provider:Z.provider,model:J,effort:Y,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(L){G.cancelled=L,H({ok:!1,error:Error(L)})}};$.modelSettingsChange=G;let W=Promise.resolve().then(()=>Z.setModelSettings(Q,Y)).then(()=>({ok:!0}),(L)=>({ok:!1,error:L})),K=Promise.race([W,z]),_=Symbol("model-settings-pending"),j;try{let L=await Promise.race([K,new Promise((D)=>{j=setTimeout(()=>D(_),20000)})]);if(L!==_)return await rQ($,G,L);let q=`正在等待 ${c0(Z.provider)} 确认 ${J} / ${Y},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:q,card:u6($.sessionName,!0,q),completion:K.then((D)=>$.finishModelSettingsChange(G,D))}}finally{clearTimeout(j)}}function sO($){let Z=$.currentTokenSource();return u0().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 eQ($,Z,J=Z.models){let Q=$.currentModelLabel(),Y=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let H=V&&Q===X.model;return{provider:Z.agent,sourceId:Z.id,model:X.model,displayName:X.display,description:X.unavailableReason??(X.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:X.unavailableReason,origin:X.origin,enabled:!0,isDefault:!1,selected:H,efforts:X.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===X.defaultEffort,selected:H&&Y===z}))}})}async function LK($){let Z=aO(),J=sO($);$.modelPanels.set(Z,{models:[]});let Q,Y=await i($.chatId,zQ({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}),(V)=>{Q=V});if(!Y)$.modelPanels.delete(Z),await g($.chatId,`❌ 模型面板发送失败:${k(Q)}`);else{let V=$.modelPanels.get(Z);if(V)V.messageId=Y}}async function $Y($,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=eQ($,Y),H=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Q,messageId:H,mode:"select",editable:!!Y.modelSelection,sourceRevision:Y.spawnRevision}),X7($,V,Q,0)}async function X7($,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/tQ));if(!Number.isInteger(Q)||Q<0||Q>=V)return{ok:!1,message:"模型页码无效"};return Y.models=Y.catalog.slice(Q*tQ,(Q+1)*tQ),Y.page=Q,Y.totalPages=V,{ok:!0,message:"",card:GQ({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 PK($,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:eQ($,Y,V),sourceId:J,messageId:Q.messageId,mode:"add",editable:!0,sourceRevision:Y.spawnRevision}),X7($,Z,J,0)}async function DK($,Z,J,Q,Y){let V=$.modelPanels.get(Z),X=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!X?.modelSelection||V.sourceRevision!==X.spawnRevision||V.mode!==(Y==="add"?"add":"select")||!V.models.some((H)=>H.model===Q))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Y==="delete"){let H=[...R$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Q.replace(/\[1m\]$/,""));if(H.length)return{ok:!1,message:`补录模型仍被会话 ${H.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Y==="delete")await $G(J,Q,$.codexAccountId());else await rz(J,Q,Y,$.codexAccountId());for(let z of R$.all)for(let[G,W]of z.modelPanels)if(W.sourceId===J&&(z!==$||G!==Z))z.modelPanels.delete(G);return{...await $Y($,J,Z),message:Y==="add"?"模型已显示":Y==="delete"?"补录模型已删除":"模型已隐藏"}}catch(H){return{ok:!1,message:`模型列表更新失败:${x(H)}`}}}async function FK($,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 UK($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),V=$.tokenSource(Q.sourceId),X=[],H=async(j)=>{if(!Q.cardMessageId)return!1;let L="",q=!1,D=!1;try{L=await h$(Q.cardMessageId),A$(L,1);let F;if(q=await K0(L,C.modelPanel,j,{notifyCardFailure:!1,onFailure:(M)=>{F=M}}),!q)throw Error(`model panel replace rejected: ${k(F)}`);let U;if(D=await C0(L,{config:{streaming_mode:!1}},(M)=>{U=M}),!D)throw Error(`model panel streaming-off rejected: ${k(U)}`)}catch(F){B(`model-custom: card update MISS (${F?.message??F})`),X.push(x(F))}finally{if(L){if(!D)try{let F;if(D=await C0(L,{config:{streaming_mode:!1}},(U)=>{F=U}),!D)X.push(`model panel streaming-off rejected: ${k(F)}`)}catch(F){B(`model-custom: streaming-off retry MISS (${F?.message??F})`),X.push(k(F))}if(q&&D)try{await B$(L)}catch(F){B(`model-custom: card dispose MISS (${F?.message??F})`)}else B(`model-custom: retain card state after checked MISS mutation=${q} streamingOff=${D} card=${L.slice(0,12)}`)}}return q&&D},z=async(j,L)=>{if(await H(j))return!0;let D=[...new Set(X)].join(`
246
+ `)}`)});H.add(G),G.finally(()=>{if(H.delete(G),!H.size)X.delete(Y)}).catch((W)=>B(`generated image failure notice failed: ${W}`))}async function oQ($,Z){let J=Z?[...$.imageDeliveryInflight?.get(Z)??[]]:[...$.imageDeliveryInflight?.values()??[]].flatMap((Q)=>[...Q]);await Promise.allSettled(J)}function mO($,Z,J,Q,Y,V,X){if(!$.currentTurn)return;if(!V)$.taskBoard=EQ($.taskBoard,J,Q,Y);let H=k1(Z.i,$.taskBoard,{name:J,status:V?"❌":"✅"},X);if(P0($.currentTurn.cardId,C.tool(Z.i),H),$.currentTurn.taskLiveInserted)K0($.currentTurn.cardId,C.taskBoardLive,P2($.taskBoard),{notifyCardFailure:!1});M2($)}function M2($){let Z=$.currentTurn;if(!Z||$.hasPendingAgentTool())return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function sQ($,Z,J,Q,Y,V=$.currentTurn){let X=V;if(!X)return;for(let[H,z]of Q){if(X.toolByUseId.has(H))continue;let G=z.batchSlot??null,W=z.input,K,_;if(G!=null){let M=Y.get(z.i)?.items[G];if(!M)continue;W=M.input,K=M.output,_=M.isError}else K=z.output??null,_=z.isError??!1;let j=K!=null,L=F4(Z,C.tool(z.i));if(j&&!L)continue;if(G!=null){let M=Y.get(z.i)?.kind;if(!M)continue;let U=X.toolCount++,O={toolUseId:H,input:W,output:K,isError:_};X.toolBatches.set(U,{kind:M,items:[O]}),X.toolByUseId.set(H,{...z,i:U,batchSlot:0}),N0(J,XK(M,U,[O]),{type:"insert_before",targetElementId:k0(X)});continue}let q=L2(z.name);if(q){let M=q==="TaskCreate";if(M)X.taskUpdateI=null;else X.taskCreateI=null;let U=(M?X.taskCreateI:X.taskUpdateI)===null;if(U)if(M)X.taskCreateI=X.toolCount++;else X.taskUpdateI=X.toolCount++;let O=M?X.taskCreateI:X.taskUpdateI;X.toolByUseId.set(H,{...z,i:O});let A=!j?"⏳":_?"❌":"✅",T=k1(O,$.taskBoard,{name:q,status:A},z.resolvedNote);U?N0(J,T,{type:"insert_before",targetElementId:k0(X)}):P0(J,C.tool(O),T);continue}let D=X.toolCount++;X.toolByUseId.set(H,{...z,i:D});let F=!j?"⏳":_?"❌":"✅";N0(J,p$(D,z.name,z.input,K,F,z.resolvedNote,z.imageKey),{type:"insert_before",targetElementId:k0(X)})}}var GK=R(()=>{vQ();Z1();L$();e();I();Y7()});async function WK($,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 H=$.currentTurn,z=H?.toolByUseId.get(Y.toolUseId);if(H&&z){let G=L2(z.name);if(J==="deny"){let W=`\uD83D\uDEAB 已拒绝 by ${Q||"匿名"}`,K=G?k1(z.i,$.taskBoard,{name:G,status:"❌"},W):p$(z.i,z.name,z.input,W,"❌");P0(H.cardId,C.tool(z.i),K)}else{let W=J==="allow_always"?"始终允许":"已允许";z.resolvedNote=`✅ **${W}** by ${Q||"匿名"}`;let K=G?k1(z.i,$.taskBoard,{name:G,status:"⏳"},z.resolvedNote):p$(z.i,z.name,z.input,null,"⏳",z.resolvedNote);P0(H.cardId,C.tool(z.i),K)}}if(B(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Y.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function KK($,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)aQ($,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=QQ(Y.i,Y.name,Y.input,Z.request_id);if(P0(J.cardId,C.tool(Y.i),V),J.userOpenId&&J.messageId){let X=x1(Y.name,Y.input),H=K2(Y.name),z=X&&X.length>30?X.slice(0,30)+"…":X,G=z?`\uD83D\uDD10 等审批: ${H} · ${z}`:`\uD83D\uDD10 等审批: ${H}`;(async()=>{i0(J.cardId),await z6(J.cardId,{config:{summary:{content:G}}}),await e1(J.messageId,[J.userOpenId])})()}}var BK=R(()=>{Z1();L$();e();I();Y7()});function uO($){let Z=!1,J=()=>{},Q=()=>{},Y=$.sessionId,V=()=>{$.off("context_compacted",z),$.off("exit",G),$.off("error",W)},X=(_)=>{if(Z)return;Z=!0,V(),J(_)},H=(_)=>{if(Z)return;Z=!0,V(),Q(_)},z=(_)=>{if(_.phase==="start")return;if(_.threadId&&Y&&_.threadId!==Y)return;X(_)},G=()=>H(Error(`${$.provider} process exited before context compaction completed`)),W=(_)=>H(_ instanceof Error?_:Error(String(_))),K=new Promise((_,j)=>{J=_,Q=j});return $.on("context_compacted",z),$.once("exit",G),$.once("error",W),{promise:K,cancel(){if(Z)return;Z=!0,V()}}}function dO($,Z){let J=[],Q=new Set,Y=(H,z)=>{let G=z.threadId??Z;if(G&&H.threadId&&H.threadId!==G)return!1;if(z.turnId)return H.turnId===z.turnId;return!0},V=(H)=>{for(let z=J.length-1;z>=0;z--){let G=J[z];if(G&&Y(G,H))return G}return null},X=(H)=>{if(Z&&H.threadId&&H.threadId!==Z)return;let z={usage:H.usage,contextWindow:H.contextWindow,threadId:H.threadId,turnId:H.turnId};J.push(z);for(let G of[...Q])if(Y(z,G.notice))G.finish(z)};return $.on("token_usage",X),{waitFor(H,z){let G=V(H);if(G)return Promise.resolve(G);return new Promise((W)=>{let K=null,_={notice:H,finish:(j)=>{if(K)clearTimeout(K);Q.delete(_),W(j)}};K=setTimeout(()=>_.finish(null),z),Q.add(_)})},cancel(){$.off("token_usage",X);for(let H of[...Q])H.finish(null)}}}function iO($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=U6($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=O6($.contextWindow);return` · \uD83E\uDDE0 ${DG(Z,J)} (${A6(Z,J)})`}async function _K($){$.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?x0(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)},H=uO(J),z=dO(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(V,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(V,$.withModel("⏳ 等待压缩完成事件"));let G=await H.promise,W=await z.waitFor(G,lO),K=G.threadId?` thread=${x0(G.threadId)}`:"";await X($.withModel(`✅ 上下文已压缩${K}${iO(W)}`))}catch(G){if(H.cancel(),G instanceof l1)await X($.withModel(`ⓘ ${G.message}`));else await X(`❌ 上下文压缩失败: ${x(G)}`)}finally{z.cancel(),$.manualContextCompactionPending=!1}}var lO=1500;var jK=R(()=>{B0();e()});import{randomUUID as aO}from"node:crypto";function qK($,Z){return{ok:!1,message:Z,card:u6($.sessionName,!1,Z)}}async function rQ($,Z,J){if(Z.cancelled||$.modelSettingsChange!==Z||$.proc!==Z.proc||!Z.proc.isAlive())return qK($,`本次模型切换未保存:${Z.cancelled??"原进程已退出或更换"}${J.ok?"":`;${x(J.error)}`}`);Z.confirmedModel=J.ok||J.error instanceof p2&&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}`),qK($,Z.error);return $.modelSettingsChange=null,$.modelPanels.delete(Z.panelId),$.resumeInputAfterModelSettingsChange(),{ok:!0,message:`已选择 ${c0(Z.provider)} · ${Z.model} / ${Z.effort}`,card:Q3({sessionName:$.sessionName,provider:Z.provider,model:Z.model,effort:Z.effort,scope:ZY($,Z.provider)})}}async function oO($,Z,J,Q,Y,V,X){let H,z=new Promise((L)=>{H=L}),G={proc:Z,provider:Z.provider,model:J,effort:Y,sourceId:X,panelId:V,phase:"pending",confirmedModel:null,confirmedEffort:null,cancel(L){G.cancelled=L,H({ok:!1,error:Error(L)})}};$.modelSettingsChange=G;let W=Promise.resolve().then(()=>Z.setModelSettings(Q,Y)).then(()=>({ok:!0}),(L)=>({ok:!1,error:L})),K=Promise.race([W,z]),_=Symbol("model-settings-pending"),j;try{let L=await Promise.race([K,new Promise((D)=>{j=setTimeout(()=>D(_),20000)})]);if(L!==_)return await rQ($,G,L);let q=`正在等待 ${c0(Z.provider)} 确认 ${J} / ${Y},尚不能判断切换结果。确认后会更新本卡;仍可回答 Agent 提问或用 stop 打断任务,取消本次切换请发 kill 或 restart。`;return{ok:!1,pending:!0,message:q,card:u6($.sessionName,!0,q),completion:K.then((D)=>$.finishModelSettingsChange(G,D))}}finally{clearTimeout(j)}}function sO($){let Z=$.currentTokenSource();return u0().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 eQ($,Z,J=Z.models){let Q=$.currentModelLabel(),Y=$.currentEffortLabel(),V=$.currentTokenSource()?.id===Z.id;return J.map((X)=>{let H=V&&Q===X.model;return{provider:Z.agent,sourceId:Z.id,model:X.model,displayName:X.display,description:X.unavailableReason??(X.efforts.length?"":"effort MISS:上游未声明该后端支持的推理档位"),unavailableReason:X.unavailableReason,origin:X.origin,enabled:!0,isDefault:!1,selected:H,efforts:X.efforts.map((z)=>({effort:z,description:z==="default"?"模型未提供 effort 档位,使用模型原生行为。":"",isDefault:z===X.defaultEffort,selected:H&&Y===z}))}})}async function LK($){let Z=aO(),J=sO($);$.modelPanels.set(Z,{models:[]});let Q,Y=await i($.chatId,zQ({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J}),(V)=>{Q=V});if(!Y)$.modelPanels.delete(Z),await g($.chatId,`❌ 模型面板发送失败:${k(Q)}`);else{let V=$.modelPanels.get(Z);if(V)V.messageId=Y}}async function $Y($,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=eQ($,Y),H=$.modelPanels.get(V)?.messageId;return $.modelPanels.set(V,{models:[],catalog:X,sourceId:Q,messageId:H,mode:"select",editable:!!Y.modelSelection,sourceRevision:Y.spawnRevision}),X7($,V,Q,0)}async function X7($,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/tQ));if(!Number.isInteger(Q)||Q<0||Q>=V)return{ok:!1,message:"模型页码无效"};return Y.models=Y.catalog.slice(Q*tQ,(Q+1)*tQ),Y.page=Q,Y.totalPages=V,{ok:!0,message:"",card:GQ({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 PK($,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:eQ($,Y,V),sourceId:J,messageId:Q.messageId,mode:"add",editable:!0,sourceRevision:Y.spawnRevision}),X7($,Z,J,0)}async function DK($,Z,J,Q,Y){let V=$.modelPanels.get(Z),X=$.tokenSource(J);if(!V?.editable||V.sourceId!==J||!X?.modelSelection||V.sourceRevision!==X.spawnRevision||V.mode!==(Y==="add"?"add":"select")||!V.models.some((H)=>H.model===Q))return{ok:!1,message:"模型管理选项已失效,请重新发送 md"};if(Y==="delete"){let H=[...R$.all].filter((z)=>z.currentTokenSource()?.id===J&&z.currentModelLabel()===Q.replace(/\[1m\]$/,""));if(H.length)return{ok:!1,message:`补录模型仍被会话 ${H.map((z)=>z.sessionName).join("、")} 选用,请先切换再删除`}}try{if(Y==="delete")await $G(J,Q,$.codexAccountId());else await rz(J,Q,Y,$.codexAccountId());for(let z of R$.all)for(let[G,W]of z.modelPanels)if(W.sourceId===J&&(z!==$||G!==Z))z.modelPanels.delete(G);return{...await $Y($,J,Z),message:Y==="add"?"模型已显示":Y==="delete"?"补录模型已删除":"模型已隐藏"}}catch(H){return{ok:!1,message:`模型列表更新失败:${x(H)}`}}}async function FK($,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 MK($,Z,J){let Q=$.modelCustomPrompt;if(!Q)return!1;$.modelCustomPrompt=null;let Y=Z.trim(),V=$.tokenSource(Q.sourceId),X=[],H=async(j)=>{if(!Q.cardMessageId)return!1;let L="",q=!1,D=!1;try{L=await h$(Q.cardMessageId),A$(L,1);let F;if(q=await K0(L,C.modelPanel,j,{notifyCardFailure:!1,onFailure:(U)=>{F=U}}),!q)throw Error(`model panel replace rejected: ${k(F)}`);let M;if(D=await C0(L,{config:{streaming_mode:!1}},(U)=>{M=U}),!D)throw Error(`model panel streaming-off rejected: ${k(M)}`)}catch(F){B(`model-custom: card update MISS (${F?.message??F})`),X.push(x(F))}finally{if(L){if(!D)try{let F;if(D=await C0(L,{config:{streaming_mode:!1}},(M)=>{F=M}),!D)X.push(`model panel streaming-off rejected: ${k(F)}`)}catch(F){B(`model-custom: streaming-off retry MISS (${F?.message??F})`),X.push(k(F))}if(q&&D)try{await B$(L)}catch(F){B(`model-custom: card dispose MISS (${F?.message??F})`)}else B(`model-custom: retain card state after checked MISS mutation=${q} streamingOff=${D} card=${L.slice(0,12)}`)}}return q&&D},z=async(j,L)=>{if(await H(j))return!0;let D=[...new Set(X)].join(`
247
247
  `),F=`⚠️ 模型补录结果未能写回原卡。${L}${D?`
248
248
  ${D}`:""}
249
- 请重新发送 model 打开面板。`;if(!await g($.chatId,F))B(`model-custom: visible fallback send MISS (${L})`);return!1},G=(j)=>z(V3(!1,Y,j),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${j}。`);if(!V||!V.enabled)return await G("账号不可用"),!0;if(!Y)return await G("模型名为空"),!0;if(V.models.some((j)=>j.model.toLowerCase()===Y.toLowerCase()))return await z(V3(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;try{await ez(V.id,Y,$.codexAccountId())}catch(j){return B(`model-custom: config/refresh MISS (${x(j)})`),await G(`配置写入或模型刷新失败:${x(j)}`),!0}B(`model-custom: ${V.id} 补录 ${Y} by ${J}(记录已持久化)`);for(let j of R$.all)for(let[L,q]of j.modelPanels)if(q.sourceId===V.id&&(j!==$||L!==Q.panelId))j.modelPanels.delete(L);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await G(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let K=eQ($,W),_=K.find((j)=>j.model===Y);if(!_)return await G("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Q.panelId,{models:K,messageId:Q.cardMessageId}),_.unavailableReason||!_.efforts.length)return await z(V3(!0,Y,`**MISS**:${_.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Y} 已补录,能力尚未确认。`),!0;if(_.efforts.length===1){let j=await $.onModelEffortSelect(_.model,_.efforts[0].effort,Q.panelId,J,_.provider),L=(q)=>z(q.pending?Y3(!0,q.message):q.ok?n6({sessionName:$.sessionName,provider:_.provider,model:_.model,effort:_.efforts[0].effort,scope:ZY($,_.provider??"codex")}):Y3(!1,q.message),q.message);if(await L(j),j.completion)j.completion.then(L).catch(async(q)=>{let D=`模型补录后的切换结果呈现失败:${x(q)}`;B(`model-custom: ${D}`),await g($.chatId,`❌ ${D}`)});return!0}return await z(i6({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:_}),`✅ 模型 ${Y} 已补录成功。`),!0}async function MK($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:d6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:d6($.sessionName)}}function tO($,Z){return C$(Z?.provider)?Z.provider:m2($)}function ZY($,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`下次启动 ${c0(Z)} 时使用。`}async function OK($,Z,J="",Q="",Y=null){let V=Z.trim();if(!V)return await b($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=tO(V,Y),H=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===X);if(!H)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(H.unavailableReason)return{ok:!1,message:H.unavailableReason};if(H.enabled===!1)return{ok:!1,message:`${H.displayName} 未配置,请先点「启用」`};if(H.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(H.efforts.length===1)return JY($,V,H.efforts[0].effort,J,Q,X);return{ok:!0,message:"",card:WQ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:H})}}async function JY($,Z,J,Q="",Y="",V=""){if($.modelSettingsChangesClosed)return{ok:!1,message:"daemon 正在停止,本次模型选择未执行"};if($.modelSettingsChange?.proc===$.proc&&$.modelSettingsChange?.phase==="pending")return{ok:!1,message:"上一项模型设置仍在等待后端确认,本次选择未执行;请等待结果,取消切换请发 kill 或 restart。"};let X=Z.trim(),H=J.trim();if(!X)return{ok:!1,message:"模型为空"};let z=Q.trim(),G=$.modelPanels.get(z),W=C$(V)?V:G?.models.find((A)=>A.model===X)?.provider??m2(X);if(W==="dsh"){if(!F0(H))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(W==="claude"){if(!A0(H))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!W$(H))return{ok:!1,message:"Codex reasoning effort 无效"};let K=H,_=G?.models.find((A)=>A.model===X&&(A.provider??"codex")===W);if(!_||!_.efforts.some((A)=>A.effort===K))return{ok:!1,message:`${c0(W)} · ${X}/${K} 不在选项中`};let j=$.tokenSource(_.sourceId);if(j?.modelCatalogState){if(!j.enabled||j.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${j.modelCatalogState.error??j.modelCatalogState.status}`};if(!j.models.some((A)=>A.model===X&&A.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let L=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,q=!$.processSourceMatches(j,X)||!!j?.modelEnvironmentRevision&&j.modelEnvironmentRevision($.currentModelLabel()??"")!==j.modelEnvironmentRevision(X),D=$.modelSelectionNeedsProcessStop(W,_.sourceId??$.selectedTokenSourceId,X,K);if($.currentProvider()===W&&!L&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!D&&!q)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${c0(W)} · ${X} / ${K}`,card:Q3({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 后再切换到 ${c0(W)}`};let M=$.currentModelLabel()!==X||L,O=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((q||D)&&$.proc?.isAlive()&&O)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(W==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&M&&O)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===W&&!L&&!q&&!D){let T=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(X)??X:X;if(W==="codex")await $.proc.setModelSettings(T,K);else return await oO($,$.proc,X,T,K,z,_.sourceId)}await $.applyModelSelectionUnlocked(W,X,K,_.sourceId);let A=ZY($,W);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${c0(W)} · ${X} / ${K}`,card:Q3({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:A})}}catch(A){let T=`模型切换失败: ${x(A)}`;return B(`session "${$.sessionName}": set model settings failed: ${x(A)}`),{ok:!1,message:T}}}var tQ=20;var AK=R(()=>{B0();QY();Q0();LJ();j1();B0();L$();Z1();e();I()});import{createHash as eO}from"node:crypto";function $A($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function L3($="default"){return xK(TK($))}function RK($="default"){return ZA(TK($))}function TK($){return u0().map((Z)=>Z.forAccount?.($)??Z)}async function ZA($){let Z=xK($),Q=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((z)=>z.tokenSourceId===V.id);if(X)return X;let H=await JA(V);return H===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:H}}))).filter((V)=>V!==null),Y=new Set(Q.map((V)=>V.tokenSourceId));return EK(Z.identities.filter((V)=>!Y.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Y.has(V.tokenSourceId)),...Q])}function JA($){return QA($)}async function QA($){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 xK($){let Z=[],J=[];for(let Q of $)YA(Q,Z,J);return EK(Z,J)}function EK($,Z){return{catalogGeneration:eO("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function YA($,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(VA($,Y,Q))}function VA($,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:$A($.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:NK($.defaultModel)===NK(Z.model),status:Q,...Y?{reason:Y}:{},spawnRevision:$.spawnRevision}}function NK($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var H7=R(()=>{I();Q0()});import{randomUUID as XA}from"node:crypto";async function SK($,Z){if(!Z.trim()){await g($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}kK();let J=`agents_${XA()}`;P3.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()});let Q;if(!await i($.chatId,bK(J),(V)=>{Q=V}))await g($.chatId,`❌ agents 面板发送失败
249
+ 请重新发送 model 打开面板。`;if(!await g($.chatId,F))B(`model-custom: visible fallback send MISS (${L})`);return!1},G=(j)=>z(V3(!1,Y,j),`❌ ${Y?`模型 ${Y}`:"模型名"} 未加入:${j}。`);if(!V||!V.enabled)return await G("账号不可用"),!0;if(!Y)return await G("模型名为空"),!0;if(V.models.some((j)=>j.model.toLowerCase()===Y.toLowerCase()))return await z(V3(!1,Y,"已在列表中"),`ℹ️ 模型 ${Y} 已在列表中,未重复加入。`),!0;try{await ez(V.id,Y,$.codexAccountId())}catch(j){return B(`model-custom: config/refresh MISS (${x(j)})`),await G(`配置写入或模型刷新失败:${x(j)}`),!0}B(`model-custom: ${V.id} 补录 ${Y} by ${J}(记录已持久化)`);for(let j of R$.all)for(let[L,q]of j.modelPanels)if(q.sourceId===V.id&&(j!==$||L!==Q.panelId))j.modelPanels.delete(L);let W=$.tokenSource(V.id);if(!W||W.modelCatalogState?.status!=="ready")return await G(W?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let K=eQ($,W),_=K.find((j)=>j.model===Y);if(!_)return await G("补录已保存,但刷新后的模型列表未返回该项"),!0;if($.modelPanels.set(Q.panelId,{models:K,messageId:Q.cardMessageId}),_.unavailableReason||!_.efforts.length)return await z(V3(!0,Y,`**MISS**:${_.unavailableReason??"后端未确认 effort"}。记录已保存,可在模型面板删除。`),`模型 ${Y} 已补录,能力尚未确认。`),!0;if(_.efforts.length===1){let j=await $.onModelEffortSelect(_.model,_.efforts[0].effort,Q.panelId,J,_.provider),L=(q)=>z(q.pending?Y3(!0,q.message):q.ok?n6({sessionName:$.sessionName,provider:_.provider,model:_.model,effort:_.efforts[0].effort,scope:ZY($,_.provider??"codex")}):Y3(!1,q.message),q.message);if(await L(j),j.completion)j.completion.then(L).catch(async(q)=>{let D=`模型补录后的切换结果呈现失败:${x(q)}`;B(`model-custom: ${D}`),await g($.chatId,`❌ ${D}`)});return!0}return await z(i6({sessionName:$.sessionName,panelId:Q.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:_}),`✅ 模型 ${Y} 已补录成功。`),!0}async function UK($,Z=""){let J=Z.trim(),Q=$.modelCustomPrompt;if(!J||!Q||Q.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:d6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:d6($.sessionName)}}function tO($,Z){return C$(Z?.provider)?Z.provider:m2($)}function ZY($,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`下次启动 ${c0(Z)} 时使用。`}async function OK($,Z,J="",Q="",Y=null){let V=Z.trim();if(!V)return await b($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let X=tO(V,Y),H=$.modelPanels.get(J.trim())?.models.find((z)=>z.model===V&&(z.provider??"codex")===X);if(!H)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if($.modelPanels.get(J.trim())?.mode==="add")return{ok:!1,message:"请先将模型添加到可选列表"};if(H.unavailableReason)return{ok:!1,message:H.unavailableReason};if(H.enabled===!1)return{ok:!1,message:`${H.displayName} 未配置,请先点「启用」`};if(H.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};if(H.efforts.length===1)return JY($,V,H.efforts[0].effort,J,Q,X);return{ok:!0,message:"",card:WQ({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:H})}}async function JY($,Z,J,Q="",Y="",V=""){if($.modelSettingsChangesClosed)return{ok:!1,message:"daemon 正在停止,本次模型选择未执行"};if($.modelSettingsChange?.proc===$.proc&&$.modelSettingsChange?.phase==="pending")return{ok:!1,message:"上一项模型设置仍在等待后端确认,本次选择未执行;请等待结果,取消切换请发 kill 或 restart。"};let X=Z.trim(),H=J.trim();if(!X)return{ok:!1,message:"模型为空"};let z=Q.trim(),G=$.modelPanels.get(z),W=C$(V)?V:G?.models.find((A)=>A.model===X)?.provider??m2(X);if(W==="dsh"){if(!F0(H))return{ok:!1,message:"DSH reasoning effort 无效"}}else if(W==="claude"){if(!A0(H))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!W$(H))return{ok:!1,message:"Codex reasoning effort 无效"};let K=H,_=G?.models.find((A)=>A.model===X&&(A.provider??"codex")===W);if(!_||!_.efforts.some((A)=>A.effort===K))return{ok:!1,message:`${c0(W)} · ${X}/${K} 不在选项中`};let j=$.tokenSource(_.sourceId);if(j?.modelCatalogState){if(!j.enabled||j.modelCatalogState.status!=="ready")return{ok:!1,message:`模型目录 MISS:${j.modelCatalogState.error??j.modelCatalogState.status}`};if(!j.models.some((A)=>A.model===X&&A.efforts.includes(K)))return{ok:!1,message:"模型或 effort 已不在账号目录中,请重新发送 model"}}let L=!!_.sourceId&&$.currentTokenSource()?.id!==_.sourceId,q=!$.processSourceMatches(j,X)||!!j?.modelEnvironmentRevision&&j.modelEnvironmentRevision($.currentModelLabel()??"")!==j.modelEnvironmentRevision(X),D=$.modelSelectionNeedsProcessStop(W,_.sourceId??$.selectedTokenSourceId,X,K);if($.currentProvider()===W&&!L&&$.currentModelLabel()===X&&$.currentEffortLabel()===K&&!$.modelSettingsChange&&!D&&!q)return $.modelPanels.delete(z),{ok:!0,message:`当前已是 ${c0(W)} · ${X} / ${K}`,card:Q3({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 后再切换到 ${c0(W)}`};let U=$.currentModelLabel()!==X||L,O=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if((q||D)&&$.proc?.isAlive()&&O)return{ok:!1,message:"新模型需要更新进程配置,请等当前任务结束后再选择"};if(W==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&U&&O)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===W&&!L&&!q&&!D){let T=_.sourceId?$.tokenSource(_.sourceId)?.resolveSpawnModel(X)??X:X;if(W==="codex")await $.proc.setModelSettings(T,K);else return await oO($,$.proc,X,T,K,z,_.sourceId)}await $.applyModelSelectionUnlocked(W,X,K,_.sourceId);let A=ZY($,W);return $.modelPanels.delete(z),{ok:!0,message:`已选择 ${c0(W)} · ${X} / ${K}`,card:Q3({sessionName:$.sessionName,provider:W,model:X,effort:K,scope:A})}}catch(A){let T=`模型切换失败: ${x(A)}`;return B(`session "${$.sessionName}": set model settings failed: ${x(A)}`),{ok:!1,message:T}}}var tQ=20;var AK=R(()=>{B0();QY();Q0();LJ();j1();B0();L$();Z1();e();I()});import{createHash as eO}from"node:crypto";function $A($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function L3($="default"){return xK(TK($))}function RK($="default"){return ZA(TK($))}function TK($){return u0().map((Z)=>Z.forAccount?.($)??Z)}async function ZA($){let Z=xK($),Q=(await Promise.all($.filter((V)=>V.kind==="claude-subscription").map(async(V)=>{let X=Z.sourceFailures.find((z)=>z.tokenSourceId===V.id);if(X)return X;let H=await JA(V);return H===null?null:{tokenSourceId:V.id,display:V.display,status:"failed",reason:H}}))).filter((V)=>V!==null),Y=new Set(Q.map((V)=>V.tokenSourceId));return EK(Z.identities.filter((V)=>!Y.has(V.tokenSourceId)),[...Z.sourceFailures.filter((V)=>!Y.has(V.tokenSourceId)),...Q])}function JA($){return QA($)}async function QA($){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 xK($){let Z=[],J=[];for(let Q of $)YA(Q,Z,J);return EK(Z,J)}function EK($,Z){return{catalogGeneration:eO("sha256").update(JSON.stringify({identities:$,sourceFailures:Z})).digest("hex").slice(0,16),identities:$,sourceFailures:Z}}function YA($,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(VA($,Y,Q))}function VA($,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:$A($.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:NK($.defaultModel)===NK(Z.model),status:Q,...Y?{reason:Y}:{},spawnRevision:$.spawnRevision}}function NK($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var H7=R(()=>{I();Q0()});import{randomUUID as XA}from"node:crypto";async function SK($,Z){if(!Z.trim()){await g($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}kK();let J=`agents_${XA()}`;P3.set(J,{ownerOpenId:Z,codexAccountId:$.codexAccountId(),page:0,createdAt:Date.now()});let Q;if(!await i($.chatId,bK(J),(V)=>{Q=V}))await g($.chatId,`❌ agents 面板发送失败
250
250
  ${k(Q)}`)}function CK($,Z,J){let Q=GA($,J),Y=Number(Z);if(!Number.isInteger(Y))return WA("无效页码");let V=zA(Q.codexAccountId);return Q.page=Math.max(0,Math.min(V-1,Y)),Q.createdAt=Date.now(),{ok:!0,message:"已更新",card:bK($)}}function bK($){let Z=P3.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=L3(Z.codexAccountId),Q=Math.max(1,Math.ceil(J.identities.length/z7));Z.page=Math.min(Z.page,Q-1);let Y=Z.page*z7;return NQ({panelId:$,page:Z.page,totalPages:Q,catalog:J.identities.slice(Y,Y+z7),failures:J.sourceFailures})}function zA($){return Math.max(1,Math.ceil(L3($).identities.length/z7))}function GA($,Z){kK();let J=P3.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function WA($){return{ok:!1,message:$,card:b1({title:"agents",message:$,ok:!1})}}function kK(){let $=Date.now()-HA;for(let[Z,J]of P3)if(J.createdAt<$)P3.delete(Z)}var z7=8,HA=1800000,P3;var wK=R(()=>{L$();e();H7();P3=new Map});var XY={};d$(XY,{withTasklistLifecycleLock:()=>B7,tasklistNameForProject:()=>K7,reconcileTasklistDeletions:()=>jA,isTasklistAlreadyDeletedError:()=>yK,getTasklistBinding:()=>X1,enableTasklist:()=>YY,deleteTasklistRemoteIdempotently:()=>vK,deleteTasklist:()=>VY});import{existsSync as BA,readFileSync as _A}from"node:fs";function K7($){return`${$}[lodestar]`}function X1($){let Z=V1.get($);return Z?b4(Z):null}async function B7($,Z){let J=G7.get($)??Promise.resolve(),Q,Y=new Promise((X)=>{Q=X}),V=J.catch(()=>{}).then(()=>Y);G7.set($,V),await J.catch(()=>{});try{return await Z()}finally{if(Q(),G7.get($)===V)G7.delete($)}}function yK($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function vK($,Z=WZ){try{return await Z($),"deleted"}catch(J){if(yK(J))return"already_deleted";throw J}}async function YY($,Z){return await B7($,async()=>{let J=X1($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Q=K7($);if(Q.length>100)throw Error(`tasklist name is too long (${Q.length}/100): ${Q}`);let Y=await zZ(Z),V=await GZ(Q,Y),X={guid:V.guid,name:V.name,url:V.url,projectName:$,ownerOpenId:Y,createdAt:V.createdAt};return W7($,X),b4(X)})}async function VY($,Z){return await B7($,async()=>{let J=X1($);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},W7($,J);return await fK($,Z)})}async function fK($,Z){let J=X1($);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,W7($,J);try{if(await vK(Z)==="already_deleted")B(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Y=new Map(V1);return Y.delete($),hK(Y),V1.delete($),b4(J)}catch(Q){let Y=X1($);if(Y?.guid===Z&&Y.deleting)Y.deleting.lastError=Q instanceof Error?Q.message:String(Q),W7($,Y);throw Q}}async function jA(){let $=[...V1.entries()].filter(([,J])=>!!J.deleting).map(([J,Q])=>({projectName:J,guid:Q.guid})),Z=[];for(let J of $)try{await B7(J.projectName,()=>fK(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 qA(){if(!BA(T3))return;try{let $=JSON.parse(_A(T3,"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:LA(Q.deleting)};V1.set(Z,Y)}B(`tasklist: loaded ${V1.size} project bindings`)}catch($){B(`tasklist: load map failed: ${$}`)}}function LA($){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 W7($,Z){let J=new Map(V1);J.set($,b4(Z)),hK(J),V1.set($,b4(Z))}function hK($=V1){let Z={};for(let[J,Q]of $)Z[J]=b4(Q);o(T3,Z)}function b4($){return JSON.parse(JSON.stringify($))}var V1,G7;var HY=R(()=>{V0();e();I();v0();V1=new Map,G7=new Map;qA()});function y1($,Z,J=!1){let Q=$.worktreeProjectName();return OQ({projectName:Q,tasklistName:K7(Q),binding:X1(Q),notice:Z,confirmDelete:J})}async function IK($){let Z;if(!await i($.chatId,y1($),(Q)=>{Z=Q}))await g($.chatId,`❌ task 面板发送失败
251
- ${k(Z)}`)}async function gK($){let Z=$.worktreeProjectName();try{let J=X1(Z),Q=await YY(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:y1($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${x(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${x(J)}`),{ok:!1,message:Q,card:y1($,{type:"error",content:`❌ ${Q}`})}}}function mK($,Z){let J=$.worktreeProjectName(),Q=X1(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:y1($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:y1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:y1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function pK($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let V=`已删除 ${(await VY(J,Q)).name}`;return{ok:!0,message:V,card:y1($,{type:"success",content:`✅ ${V}`})}}catch(Y){let V=`删除失败: ${x(Y)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${x(Y)}`),{ok:!1,message:V,card:y1($,{type:"error",content:`❌ ${V}`})}}}var cK=R(()=>{L$();e();I();HY()});import{open as DA}from"node:fs/promises";import{basename as FA}from"node:path";function zY($){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 H1($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class lK{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:X0,getToken:y$,retry:p1,wait:(Z)=>new Promise((J)=>setTimeout(J,Z)),intervalMs:250}){this.deps=$}request($,Z,J="GET",Q,Y){let V=this.queue.then(()=>this.deps.retry($,async()=>{Y?.throwIfAborted();let X=await this.deps.getToken(),H=Q?.(),z=H instanceof FormData,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(OA),K=new AbortController,_=()=>K.abort(W.reason),j=()=>K.abort(Y.reason);W.addEventListener("abort",_,{once:!0}),Y?.addEventListener("abort",j,{once:!0});let L=K.signal;try{let q=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!z&&H!==void 0?{"Content-Type":"application/json"}:{}},...H!==void 0?{body:z?H:JSON.stringify(H)}:{},signal:L});return(await z$(q,$)).data}catch(q){if(L.aborted&&L.reason?.name==="TimeoutError")throw L.reason;throw q}finally{W.removeEventListener("abort",_),Y?.removeEventListener("abort",j)}}));return this.queue=V.then(()=>{},()=>{}),V}async createFolder($,Z){let J=await this.request("创建交付文件夹","/drive/v1/files/create_folder","POST",()=>({name:$,folder_token:""}),Z);return{token:H1(J?.token,"交付文件夹"),url:zY(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return H1(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Q=H1(J?.token,"群文件夹");if(Q!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Q,url:zY($.url),name:H1(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){H1(Z,"交付群"),H1(J,"交付发起人");let Y=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let X of[{member_type:"openid",member_id:J,perm:"full_access",type:"user"},{member_type:"openchat",member_id:Z,perm:"view",type:"chat"}])await this.request("设置交付文件夹权限",Y,"POST",()=>X,Q);let V=await this.request("核对交付文件夹权限",Y,"GET",void 0,Q);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[X,H,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((W)=>W.member_type===X&&W.member_id===H)?.perm!==z)throw Error(`交付文件夹权限未生效:${X} / ${z}`)}async closeFileLinkSharing($,Z){H1($,"交付文件");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 DA($,"r");try{let V=await Y.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=FA($),H={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=UA){let q=await Y.readFile(),D=await Y.stat();if(q.length!==V.size||D.mtimeMs!==V.mtimeMs||D.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let F=new FormData;for(let[U,M]of Object.entries(H))F.append(U,String(M));return F.append("file",new Blob([Uint8Array.from(q)]),X),F},Q)}else{let q=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>H,Q),D=H1(q?.upload_id,"分片上传事务"),F=q?.block_size,U=q?.block_num;if(!Number.isSafeInteger(F)||F<=0||F>MA||!Number.isSafeInteger(U)||U!==Math.ceil(V.size/F))throw Error("云空间返回的分片策略无效");for(let O=0;O<U;O++){Q?.throwIfAborted();let A=Math.min(F,V.size-O*F),T=Buffer.alloc(A),y=0;while(y<A){let S=await Y.read(T,y,A-y,O*F+y);if(!S.bytesRead)throw Error("交付文件在分片读取时发生变化");y+=S.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let S=new FormData;return S.append("upload_id",D),S.append("seq",String(O)),S.append("size",String(A)),S.append("file",new Blob([Uint8Array.from(T)]),X),S},Q)}let M=await Y.stat();if(M.size!==V.size||M.mtimeMs!==V.mtimeMs||M.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:D,block_num:U}),Q)}let G=H1(z?.file_token,"已上传文件"),W={token:G,url:"",name:X,bytes:V.size},K=[];try{J(W)}catch(q){K.push(q)}try{await this.closeFileLinkSharing(G)}catch(q){K.push(q)}if(K.length===1)throw K[0];if(K.length>1)throw AggregateError(K,K.map((q)=>q instanceof Error?q.message:String(q)).join(";"));Q?.throwIfAborted();let _=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:G,doc_type:"file"}],with_url:!0}),Q),j=_?.metas?.find((q)=>q.doc_token===G&&q.doc_type==="file");if(_?.failed_list?.length||!j)throw Error("已上传文件的元数据 MISS");let L={...W,url:zY(j.url)};return J(L),L}finally{await Y.close()}}}var UA=20971520,MA=20971520,OA=60000,M2;var uK=R(()=>{o0();e();b2();M2=new lK});import{randomUUID as dK}from"node:crypto";import{basename as AA}from"node:path";class GY{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:dK(),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:dK(),path:$,name:AA($),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}
251
+ ${k(Z)}`)}async function gK($){let Z=$.worktreeProjectName();try{let J=X1(Z),Q=await YY(Z,$.chatId),Y=J?"已启用":`已启用 ${Q.name}`;return{ok:!0,message:Y,card:y1($,{type:"success",content:`✅ ${Y}`})}}catch(J){let Q=`启用失败: ${x(J)}`;return B(`session "${$.sessionName}": tasklist enable failed: ${x(J)}`),{ok:!1,message:Q,card:y1($,{type:"error",content:`❌ ${Q}`})}}}function mK($,Z){let J=$.worktreeProjectName(),Q=X1(J),Y=Z.trim();if(!Q)return{ok:!1,message:"未启用",card:y1($,{type:"error",content:"❌ 未启用"})};if(Q.guid!==Y)return{ok:!1,message:"清单绑定已变化",card:y1($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:y1($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function pK($,Z){let J=$.worktreeProjectName(),Q=Z.trim();try{let V=`已删除 ${(await VY(J,Q)).name}`;return{ok:!0,message:V,card:y1($,{type:"success",content:`✅ ${V}`})}}catch(Y){let V=`删除失败: ${x(Y)}`;return B(`session "${$.sessionName}": tasklist delete failed: ${x(Y)}`),{ok:!1,message:V,card:y1($,{type:"error",content:`❌ ${V}`})}}}var cK=R(()=>{L$();e();I();HY()});import{open as DA}from"node:fs/promises";import{basename as FA}from"node:path";function zY($){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 H1($,Z){if(typeof $!=="string"||!$.trim())throw Error(`${Z} MISS`);return $}class lK{deps;queue=Promise.resolve();lastStartedAt=0;constructor($={fetch:X0,getToken:y$,retry:p1,wait:(Z)=>new Promise((J)=>setTimeout(J,Z)),intervalMs:250}){this.deps=$}request($,Z,J="GET",Q,Y){let V=this.queue.then(()=>this.deps.retry($,async()=>{Y?.throwIfAborted();let X=await this.deps.getToken(),H=Q?.(),z=H instanceof FormData,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(OA),K=new AbortController,_=()=>K.abort(W.reason),j=()=>K.abort(Y.reason);W.addEventListener("abort",_,{once:!0}),Y?.addEventListener("abort",j,{once:!0});let L=K.signal;try{let q=await this.deps.fetch(`https://open.feishu.cn/open-apis${Z}`,{method:J,headers:{Authorization:`Bearer ${X}`,...!z&&H!==void 0?{"Content-Type":"application/json"}:{}},...H!==void 0?{body:z?H:JSON.stringify(H)}:{},signal:L});return(await z$(q,$)).data}catch(q){if(L.aborted&&L.reason?.name==="TimeoutError")throw L.reason;throw q}finally{W.removeEventListener("abort",_),Y?.removeEventListener("abort",j)}}));return this.queue=V.then(()=>{},()=>{}),V}async createFolder($,Z){let J=await this.request("创建交付文件夹","/drive/v1/files/create_folder","POST",()=>({name:$,folder_token:""}),Z);return{token:H1(J?.token,"交付文件夹"),url:zY(J?.url)}}async getChatName($,Z){let J=await this.request("读取群名称",`/im/v1/chats/${encodeURIComponent($)}`,"GET",void 0,Z);return H1(J?.name,"群名称")}async getFolder($,Z){let J=await this.request("读取群文件夹",`/drive/explorer/v2/folder/${encodeURIComponent($.token)}/meta`,"GET",void 0,Z),Q=H1(J?.token,"群文件夹");if(Q!==$.token)throw Error("群文件夹返回了不同的标识");return{token:Q,url:zY($.url),name:H1(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){H1(Z,"交付群"),H1(J,"交付发起人");let Y=`/drive/v1/permissions/${encodeURIComponent($.token)}/members?type=folder`;for(let X of[{member_type:"openid",member_id:J,perm:"full_access",type:"user"},{member_type:"openchat",member_id:Z,perm:"view",type:"chat"}])await this.request("设置交付文件夹权限",Y,"POST",()=>X,Q);let V=await this.request("核对交付文件夹权限",Y,"GET",void 0,Q);if(!Array.isArray(V?.items))throw Error("交付文件夹权限列表 MISS");for(let[X,H,z]of[["openid",J,"full_access"],["openchat",Z,"view"]])if(V.items.find((W)=>W.member_type===X&&W.member_id===H)?.perm!==z)throw Error(`交付文件夹权限未生效:${X} / ${z}`)}async closeFileLinkSharing($,Z){H1($,"交付文件");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 DA($,"r");try{let V=await Y.stat();if(!V.isFile())throw Error("交付路径不是普通文件");if(!Number.isSafeInteger(V.size)||V.size<=0)throw Error("不能上传空文件或无效大小的文件");let X=FA($),H={file_name:X,parent_type:"explorer",parent_node:Z.token,size:V.size},z;if(V.size<=MA){let q=await Y.readFile(),D=await Y.stat();if(q.length!==V.size||D.mtimeMs!==V.mtimeMs||D.ctimeMs!==V.ctimeMs)throw Error("交付文件在读取时发生变化");z=await this.request("上传交付文件","/drive/v1/files/upload_all","POST",()=>{let F=new FormData;for(let[M,U]of Object.entries(H))F.append(M,String(U));return F.append("file",new Blob([Uint8Array.from(q)]),X),F},Q)}else{let q=await this.request("准备上传交付文件","/drive/v1/files/upload_prepare","POST",()=>H,Q),D=H1(q?.upload_id,"分片上传事务"),F=q?.block_size,M=q?.block_num;if(!Number.isSafeInteger(F)||F<=0||F>UA||!Number.isSafeInteger(M)||M!==Math.ceil(V.size/F))throw Error("云空间返回的分片策略无效");for(let O=0;O<M;O++){Q?.throwIfAborted();let A=Math.min(F,V.size-O*F),T=Buffer.alloc(A),y=0;while(y<A){let S=await Y.read(T,y,A-y,O*F+y);if(!S.bytesRead)throw Error("交付文件在分片读取时发生变化");y+=S.bytesRead}await this.request("上传交付文件分片","/drive/v1/files/upload_part","POST",()=>{let S=new FormData;return S.append("upload_id",D),S.append("seq",String(O)),S.append("size",String(A)),S.append("file",new Blob([Uint8Array.from(T)]),X),S},Q)}let U=await Y.stat();if(U.size!==V.size||U.mtimeMs!==V.mtimeMs||U.ctimeMs!==V.ctimeMs)throw Error("交付文件在上传期间被修改,未完成上传");z=await this.request("完成交付文件上传","/drive/v1/files/upload_finish","POST",()=>({upload_id:D,block_num:M}),Q)}let G=H1(z?.file_token,"已上传文件"),W={token:G,url:"",name:X,bytes:V.size},K=[];try{J(W)}catch(q){K.push(q)}try{await this.closeFileLinkSharing(G)}catch(q){K.push(q)}if(K.length===1)throw K[0];if(K.length>1)throw AggregateError(K,K.map((q)=>q instanceof Error?q.message:String(q)).join(";"));Q?.throwIfAborted();let _=await this.request("读取交付文件链接","/drive/v1/metas/batch_query","POST",()=>({request_docs:[{doc_token:G,doc_type:"file"}],with_url:!0}),Q),j=_?.metas?.find((q)=>q.doc_token===G&&q.doc_type==="file");if(_?.failed_list?.length||!j)throw Error("已上传文件的元数据 MISS");let L={...W,url:zY(j.url)};return J(L),L}finally{await Y.close()}}}var MA=20971520,UA=20971520,OA=60000,U2;var uK=R(()=>{o0();e();b2();U2=new lK});import{randomUUID as dK}from"node:crypto";import{basename as AA}from"node:path";class GY{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:dK(),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:dK(),path:$,name:AA($),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}
252
252
  ${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:${k(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?`
253
- 已上传文件所在文件夹:${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 iK=()=>{};class WY{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=w$(Z),Q=this.load(),Y=Q.workspaces[J]?.enabled;if(Y===void 0){let X=new Set(this.legacyChats($,J).map((H)=>Q.groups[H].legacyEnabled));if(X.size>1)throw Error("同一工作目录的旧群文件交付设置冲突,请发送 files on 或 files off 统一设置");if(X.size)Y=X.values().next().value,this.commitMode($,J,Y)}let V=this.load().groups[$]?.folder;return{enabled:Y??!1,...V?{folder:structuredClone(V)}:{}}}mode($,Z){return this.get($,Z).enabled?"drive":"chat"}enable($,Z,J){let Q=w$(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=w$(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)||!D3(Z.groups)||Z.version===2&&!D3(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Y,V]of Object.entries(Z.workspaces??{})){if(!D3(V)||typeof V.enabled!=="boolean"||w$(Y)!==Y)throw Error("工作目录文件交付开关无效");J.workspaces[Y]={enabled:V.enabled}}for(let[Y,V]of Object.entries(Z.groups)){if(!Y||!D3(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)NA(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&&w$(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 D3($){return!!$&&typeof $==="object"&&!Array.isArray($)}function NA($){if(!D3($)||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 nK=R(()=>{E8()});import{join as RA}from"node:path";import{readFileSync as TA}from"node:fs";function aK($){return new GY($,{resolveFolder:(Z,J)=>k4.resolveFolder(Z,J),uploadFile:(Z,J,Q,Y)=>M2.uploadFile(Z,J,Q,Y),sendCard:(Z,J)=>i($.chatId,fJ(Z),J),persist:(Z)=>o(RA(aY,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await b($.chatId,Z))throw Error(Z)}})}var k4;var oK=R(()=>{e();uK();iK();U6();V0();v0();I();nK();E8();k4=new WY({read:()=>{try{return TA(p7,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>o(p7,$),workDirForChat:($)=>{let Z=[..._0].filter(([,Y])=>Y===$).map(([Y])=>Y),J=j0.get($);if(!Z.length&&J)Z.push(J);let Q=new Set(Z.map((Y)=>w$(X4(Y))));if(Q.size>1)throw Error(`旧文件交付群绑定了多个工作目录: ${$}`);return Q.values().next().value},getChatName:($,Z)=>M2.getChatName($,Z),createFolder:($,Z)=>M2.createFolder($,Z),getFolder:($,Z)=>M2.getFolder($,Z),renameFolder:($,Z,J)=>M2.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Q)=>M2.grantFolderAccess($,Z,J,Q)})});async function sK($,Z,J,Q,Y,V){let X,H="",z="";try{switch(Q.trim().toLowerCase()){case"":case"status":X=Y.get($);break;case"on":X=await Y.enable($,J),H="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Y.disable($),H="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(K){z=K instanceof Error?K.message:String(K);try{X=Y.get($)}catch{X=void 0}}let G=hJ({groupName:Z,workDir:V,settings:X,notice:H,error:z}),W;if(!await Y.sendCard(G,(K)=>{W=K}))await Y.reportError(`❌ 文件交付设置卡发送失败:${k(W)}${z?`
254
- 设置失败:${z}`:""}`)}var tK=R(()=>{U6()});function rK($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
253
+ 已上传文件所在文件夹:${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 iK=()=>{};class WY{deps;state;locks=new Map;constructor($){this.deps=$}get($,Z){let J=w$(Z),Q=this.load(),Y=Q.workspaces[J]?.enabled;if(Y===void 0){let X=new Set(this.legacyChats($,J).map((H)=>Q.groups[H].legacyEnabled));if(X.size>1)throw Error("同一工作目录的旧群文件交付设置冲突,请发送 files on 或 files off 统一设置");if(X.size)Y=X.values().next().value,this.commitMode($,J,Y)}let V=this.load().groups[$]?.folder;return{enabled:Y??!1,...V?{folder:structuredClone(V)}:{}}}mode($,Z){return this.get($,Z).enabled?"drive":"chat"}enable($,Z,J){let Q=w$(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=w$(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)||!D3(Z.groups)||Z.version===2&&!D3(Z.workspaces))throw Error("文件交付设置格式无效");let J={version:2,workspaces:{},groups:{}};for(let[Y,V]of Object.entries(Z.workspaces??{})){if(!D3(V)||typeof V.enabled!=="boolean"||w$(Y)!==Y)throw Error("工作目录文件交付开关无效");J.workspaces[Y]={enabled:V.enabled}}for(let[Y,V]of Object.entries(Z.groups)){if(!Y||!D3(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)NA(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&&w$(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 D3($){return!!$&&typeof $==="object"&&!Array.isArray($)}function NA($){if(!D3($)||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 nK=R(()=>{E8()});import{join as RA}from"node:path";import{readFileSync as TA}from"node:fs";function aK($){return new GY($,{resolveFolder:(Z,J)=>k4.resolveFolder(Z,J),uploadFile:(Z,J,Q,Y)=>U2.uploadFile(Z,J,Q,Y),sendCard:(Z,J)=>i($.chatId,fJ(Z),J),persist:(Z)=>o(RA(aY,`${Z.id}.json`),Z),reportError:async(Z)=>{if(B(`file delivery ${$.projectName}: ${Z}`),!await b($.chatId,Z))throw Error(Z)}})}var k4;var oK=R(()=>{e();uK();iK();M6();V0();v0();I();nK();E8();k4=new WY({read:()=>{try{return TA(p7,"utf8")}catch($){if($?.code==="ENOENT")return;throw $}},write:($)=>o(p7,$),workDirForChat:($)=>{let Z=[..._0].filter(([,Y])=>Y===$).map(([Y])=>Y),J=j0.get($);if(!Z.length&&J)Z.push(J);let Q=new Set(Z.map((Y)=>w$(X4(Y))));if(Q.size>1)throw Error(`旧文件交付群绑定了多个工作目录: ${$}`);return Q.values().next().value},getChatName:($,Z)=>U2.getChatName($,Z),createFolder:($,Z)=>U2.createFolder($,Z),getFolder:($,Z)=>U2.getFolder($,Z),renameFolder:($,Z,J)=>U2.renameFolder($,Z,J),grantFolderAccess:($,Z,J,Q)=>U2.grantFolderAccess($,Z,J,Q)})});async function sK($,Z,J,Q,Y,V){let X,H="",z="";try{switch(Q.trim().toLowerCase()){case"":case"status":X=Y.get($);break;case"on":X=await Y.enable($,J),H="已开启此工作目录的云空间交付;同目录各群从下一轮任务生效。";break;case"off":X=await Y.disable($),H="此工作目录已恢复直接发送聊天附件;同目录各群从下一轮任务生效,云空间中的历史文件保留。";break;default:throw Error("用法:files、files on、files off")}}catch(K){z=K instanceof Error?K.message:String(K);try{X=Y.get($)}catch{X=void 0}}let G=hJ({groupName:Z,workDir:V,settings:X,notice:H,error:z}),W;if(!await Y.sendCard(G,(K)=>{W=K}))await Y.reportError(`❌ 文件交付设置卡发送失败:${k(W)}${z?`
254
+ 设置失败:${z}`:""}`)}var tK=R(()=>{M6()});function rK($){return[`- ${"生成并检查本地文件后,在回复正文中独占一行输出 `[[send: /abs/path]]` 提交交付,路径必须替换成实际存在的绝对路径。只在用户要文件或交付最终产物时使用。"}`,...$==="chat"?["- 本群通过聊天附件交付,交付前检查文件大小,单文件不超过 30 MB(30 × 1024 × 1024 字节);超限先无损压缩或分卷,保持用户要求的内容。"]:[]].join(`
255
255
  `)}function eK($,Z){let J={codex:"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",claude:"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",dsh:"- 当你有问题需要澄清时,使用 ask_user_question 工具向用户提问;不要把多选题写成文本。"};return["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。",rK(Z),"- 文件交付约定由 Lodestar 按工作目录设置生成;后续收到宿主注入的“文件交付约定更新”时,用其完整替换此前的文件交付约定。",`- ${"交付本地任务产物时,上传、权限和卡片均由 Lodestar 处理。Agent 不直接调用这些飞书接口,不为交付读取凭据或查找 token,也不依赖飞书 CLI。被委派的 Agent 只返回文件路径和说明,由主 Agent 提交交付。"}`,`- ${"交付标记只表示提交,不能据此声称上传成功。以 Lodestar 实际发出的附件、交付卡或错误提示为准,不编造云空间链接,不用其他工具重复发送。"}`,`- ${"`files`、`files on`、`files off` 是用户在群里输入的管理命令,不是 Shell 命令;不要擅自切换交付方式或改写工作目录配置。"}`,J[$],...xA].join(`
256
256
  `)}function $B($){return`[Lodestar 文件交付约定更新]
257
257
  以下约定从本轮起完整替换此前的文件交付约定:
@@ -263,24 +263,24 @@ ${k(G)}`);let K;if(!await i(H.chatId,X3({slug:Q,branch:X.branch,status:"就绪",
263
263
  ${k(K)}`)}catch(H){await b($.chatId,`❌ wt 已建,拉群失败: ${x(H)}`)}})}catch(X){await b($.chatId,`❌ wt 失败: ${x(X)}`)}}async function HB($,Z){let J=O2($),Q=w4($);return await T8(Q,async()=>{return await EA(J,Q,Z)})}async function EA($,Z,J){let Q=WH(Z,$),Y=Q.filter((H)=>H.state==="merged"&&!H.mounted).length,V=Q.filter((H)=>H.state!=="merged"||H.mounted),X=await h8();return _Q({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Y,notice:J,entries:V.map((H)=>{let z=X.get(H.chatName)??[],G=_0.get(H.chatName),W=G&&z.includes(G)?G:z.length===1?z[0]:null;return{slug:H.slug,chatName:H.chatName,branch:H.branch,state:H.state,path:H.worktreePath??H.expectedPath,mounted:H.mounted,dirtyCount:H.dirtyCount,statusLine:H.statusLine,error:H.error,chatId:W,duplicateChatCount:z.length}})})}async function _Y($){try{let Z=await HB($),J;if(!await i($.chatId,Z,(Y)=>{J=Y}))await g($.chatId,`❌ wt 列表失败
264
264
  ${k(J)}`)}catch(Z){await b($.chatId,`❌ wt 列表失败: ${x(Z)}`)}}async function ZB($,Z,J,Q){try{return{ok:Z,message:J,card:await HB($,{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}
265
265
  ${V}`,card:X3({slug:"wt",branch:"work/*",status:J,body:V,template:"red"})}}}async function zB($,Z){let J=s1(Z);if(!J)return ZB($,!1,"❌ 名称无效","error");let Q=O2($),Y=w4($),V;try{V=await T8(Y,async()=>{let X=Q4(Q,J);if($.hasRunningPeerSession(X))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${X} 群里 stop 或 kill。`,type:"error"};r5(Y,Q,J);let H=await yZ(X),z=BH(Y,Q,J);return{ok:!0,message:[`✅ ${J} 已解散`,z.removedWorktree?"dir removed":"dir missing",H.disbanded?"group removed":"group missing",z.branch].join(`
266
- `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${x(X)}`,type:"error"}}return ZB($,V.ok,V.message,V.type)}var GB=R(()=>{KY();L$();e();I();QZ()});import{closeSync as CA,openSync as bA,readSync as kA,readdirSync as wA,statSync as yA}from"node:fs";import{randomUUID as qY}from"node:crypto";import{join as vA}from"node:path";function j7($){return r$($.sessionName)??$.sessionName}function KB($){let Z=TZ($,jY);return jY.add(Z),Z}function BB($){jY.delete($)}function y4($){let Z=WB.get($);if(!Z)Z=new Map,WB.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let V=Y.status==="consumed"?IA:hA,X=Y.consumedAt??Y.createdAt;if(J-X>V)Z.delete(Q)}return Z}function mA($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function _B($,Z,J,Q){let Y={id:qY(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:j7($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return y4($).set(Y.id,Y),Y}function LY($,Z,J,Q,Y){let V=y4($).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||!mA(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 _7($){$.status="consumed",$.consumedAt=Date.now()}function pA($){return{kind:"fork",source:$.source,through:$}}function cA($){return z4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function lA($){let Z=G4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return U0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function uA($){let Z=P8($),J;try{J=wA(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(u2("claude",V))continue;let X=vA(Z,Y),H;try{H=yA(X).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${z?.message??z}`)}Q.push({provider:"claude",sessionId:V,cwd:$,preview:iA(X),ts:H})}return Q.sort((Y,V)=>V.ts-Y.ts)}function dA($){let Z=$.slice().sort((Y,V)=>V.ts-Y.ts),J=Date.now()-fA,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(gA,Math.max(10,Q)))}function iA($){let Z="",J=null;try{J=bA($,"r");let Y=Buffer.alloc(65536),V=kA(J,Y,0,65536,0);Z=Y.subarray(0,V).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)CA(J)}let Q="";for(let Y of Z.split(`
266
+ `),type:"success"}})}catch(X){V={ok:!1,message:`❌ 解散 ${J} 失败: ${x(X)}`,type:"error"}}return ZB($,V.ok,V.message,V.type)}var GB=R(()=>{KY();L$();e();I();QZ()});import{closeSync as CA,openSync as bA,readSync as kA,readdirSync as wA,statSync as yA}from"node:fs";import{randomUUID as qY}from"node:crypto";import{join as vA}from"node:path";function j7($){return r$($.sessionName)??$.sessionName}function KB($){let Z=TZ($,jY);return jY.add(Z),Z}function BB($){jY.delete($)}function y4($){let Z=WB.get($);if(!Z)Z=new Map,WB.set($,Z);let J=Date.now();for(let[Q,Y]of Z){let V=Y.status==="consumed"?IA:hA,X=Y.consumedAt??Y.createdAt;if(J-X>V)Z.delete(Q)}return Z}function mA($,Z){return $.provider===Z.provider&&($.codexAccountId??"default")===(Z.codexAccountId??"default")&&!!$.codexAccountAutomatic===!!Z.codexAccountAutomatic&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function _B($,Z,J,Q){let Y={id:qY(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:j7($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Q};return y4($).set(Y.id,Y),Y}function LY($,Z,J,Q,Y){let V=y4($).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||!mA(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 _7($){$.status="consumed",$.consumedAt=Date.now()}function pA($){return{kind:"fork",source:$.source,through:$}}function cA($){return z4($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function lA($){let Z=G4($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return M0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function uA($){let Z=P8($),J;try{J=wA(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(u2("claude",V))continue;let X=vA(Z,Y),H;try{H=yA(X).mtimeMs}catch(z){throw Error(`读取 Claude 会话元数据失败 (${Y}): ${z?.message??z}`)}Q.push({provider:"claude",sessionId:V,cwd:$,preview:iA(X),ts:H})}return Q.sort((Y,V)=>V.ts-Y.ts)}function dA($){let Z=$.slice().sort((Y,V)=>V.ts-Y.ts),J=Date.now()-fA,Q=Z.filter((Y)=>Y.ts>=J).length;return Z.slice(0,Math.min(gA,Math.max(10,Q)))}function iA($){let Z="",J=null;try{J=bA($,"r");let Y=Buffer.alloc(65536),V=kA(J,Y,0,65536,0);Z=Y.subarray(0,V).toString("utf8")}catch(Y){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Y?.message??Y}`)}finally{if(J!==null)CA(J)}let Q="";for(let Y of Z.split(`
267
267
  `)){let V=Y.trim();if(!V)continue;let X;try{X=JSON.parse(V)}catch{continue}if(X.type==="queue-operation"&&X.operation==="enqueue"&&typeof X.content==="string"){let H=X.content.trim();if(H)return H.slice(0,80)}if(!Q&&X.type==="user"&&X.message){let H=nA(X.message);if(H)Q=H}}return Q.slice(0,80)}function nA($){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 jB($,Z,J){if(!J){await b($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Q=cA($),Y=lA($),V=new Map,X=[];for(let K=0;K<Q.length;K++){let _=Q[K];if(K===0&&Y===null)continue;let j=qY(),L=K===0?Y:pA(Q[K-1].checkpoint);V.set(j,{kind:Z,launch:L,branchBase:Y,seedAnchors:Q.slice(0,K),writes:Q.slice(K).flatMap((q)=>q.writes)}),X.push({choiceId:j,preview:_.preview,ts:_.ts})}X.reverse();let H=_B($,Z,J,V),z=qQ({projectName:j7($),panelId:H.id,mode:Z,entries:X}),G,W;try{G=await i($.chatId,z,(K)=>{W=K})}catch(K){throw y4($).delete(H.id),K}if(!G)y4($).delete(H.id),await g($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败
268
268
  ${k(W)}`)}function qB($,Z){return jB($,"fork",Z)}function LB($,Z){return jB($,"back",Z)}async function PB($,Z){if(!Z){await b($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():$.selectedProvider==="dsh"?await $.listDshConversations():uA($.workDir)}catch(G){await g($.chatId,`❌ 历史会话读取失败: ${G instanceof Error?G.message:G}`);return}let Q=new Map,Y=dA(J).map((G)=>{let W=qY();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=_B($,"resume",Z,Q),X=LQ({projectName:j7($),panelId:V.id,entries:Y}),H,z;try{H=await i($.chatId,X,(G)=>{z=G})}catch(G){throw y4($).delete(V.id),G}if(!H)y4($).delete(V.id),await g($.chatId,`❌ rs 历史列表发送失败
269
- ${k(z)}`)}async function DB($,Z){if(!Z){await b($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await b($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=KB(j7($));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{BB(J)}if(!Q.ok){await b($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await b($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function FB($){if(!r$($.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 UB($,Z,J,Q){let Y=LY($,"fork",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let H=KB(V.baseName);B(`session-temp: fork ${$.sessionName} → ${H} (${X.launch.kind})`),await b($.chatId,`\uD83D\uDD31 正在分叉到 ${H}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:H,userOpenId:Q,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{BB(H)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${H};原会话和磁盘文件未回滚`}}catch(H){return{ok:!1,message:`分叉失败: ${H instanceof Error?H.message:H}`}}finally{_7(V)}}async function MB($,Z,J,Q){let Y=LY($,"back",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let H="";try{let W;if(!await i($.chatId,PQ({projectName:V.baseName,entries:X.writes}),(_)=>{W=_}))H=`;文件变更记录卡发送失败: ${k(W)}`}catch(W){H=`;文件变更记录卡发送失败: ${k(W)}`}if(B(`session-temp: back ${$.sessionName} (${X.launch.kind}, writes=${X.writes.length})`),!await $.rollbackTo(X.launch,{anchors:X.seedAnchors,base:X.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${H}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${H}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${x0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${H}`}}catch(H){return{ok:!1,message:`回退失败: ${H instanceof Error?H.message:H}`}}finally{_7(V)}}async function OB($,Z,J,Q){let Y=LY($,"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 _7(V),Error("resume panel contained a non-resume choice");let H=X.launch.source.sessionId,z=$.lastSessionId,G=(K,_)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:H,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:z,newSessionId:K,bindingState:_}),W=(K,_,j,L=null)=>({ok:K,message:_,resumePresentation:G(L,j)});try{if($.isRunning())return W(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(X.sourceStatus==="active")return W(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(B(`session-temp: history fork ${$.sessionName} ← ${X.launch.source.provider} ${H}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:z}:null}))return W(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return W(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let _=$.lastSessionId;if(!_)return W(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===H||z&&_===z)return W(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return W(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(K){return W(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{_7(V)}}var fA=86400000,hA=1800000,IA=3600000,gA=40,WB,jY;var AB=R(()=>{e();L$();I();e2();Z9();u1();WB=new WeakMap,jY=new Set});import{existsSync as NB}from"node:fs";import{randomBytes as PY,timingSafeEqual as oA}from"node:crypto";import{isAbsolute as sA}from"node:path";function FY($,Z=new Set){if($ instanceof d2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=FY(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return FY($.cause,Z);return null}function tA($){return $.itemId||$.turnId||"__latest__"}function RB($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function rA($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function eA($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function P7(){return p.runtime?.live_elapsed??"bucket"}function EB($,Z){return`${$} (${N4(Date.now()-Z,P7()).label})`}function v4($){return $.length?$.map((Z)=>`${Z.operation}: ${k(Z)}`).join(`
270
- `):k(void 0)}function YN($,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 TB="Thinking...",$N="Writing...",ZN="Working...",DY=1e4,q7=720000,JN=50,QN=256,L7=1e4,xB=250,R$;var QY=R(()=>{Z9();b9();B0();j1();SJ();B0();f0();yJ();wQ();Q0();D0();O4();e2();Z1();L$();e();I();V0();VQ();U$();TW();tZ();vQ();wW();iW();GK();Y7();BK();DJ();jK();AK();wK();cK();oK();tK();KY();GB();AB();u1();R$=class R${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=PY(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??RW(),R$.all.add(this);let Q=EZ($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=E0(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=A1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=W4($);if(V)if(this.selectedProvider!=="claude")J$($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{U0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,H=this.lastSessionRef,z=!X&&H?.provider==="claude"&&H.cwd===this.workDir&&H.sessionId!==V.launch.source.sessionId&&H.sessionId!==V.previousSessionId;if(!X&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`session "${$}": restored ${z?"materialized":"pending"} Claude fork source=${V.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0,...this.proc?.isAlive()&&this.proc.provider==="codex"&&!this.currentTokenSource()?.codexApiProvider&&this.proc.codexAccountSelectionMode?.()!==null&&!(this.proc.turnRetry?.reason==="quota"&&this.proc.turnRetry.phase==="waiting")?{codexAccountName:v.get(G$(this.proc)).name}:{}}}get workDir(){return JB(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 v5(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?G$(this.proc):this.codexStartAccountOverride??v.selected(this.sessionName)}tokenSource($){let Z=E0($);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()},...!$&&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=E0($.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)J$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;if(this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=A1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,R1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId),!Z?.codexApiProvider){let J=$.codexAccountId??c;if($.codexAccountAutomatic)v.selectAuto(this.sessionName);else if(v.selected(this.sessionName)!==J)v.select(this.sessionName,J)}}dshEffortForSpawn(){if(F0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&k$($,this.selectedModel??$.defaultModel);if(!Z||!F0(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 P4({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!u2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");let $=this.currentTokenSource();if(!$?.codexApiProvider&&!T9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(H)=>Z.spawnEnv(H):void 0,Q=new i2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J,...Z?.codexApiProvider?{apiProvider:Z.codexApiProvider}:{}}),Y=null,V=null;try{Y=await Q.listConversations()}catch(H){V=H}let X=null;try{await Q.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${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=D8(this.workDir,$.sessionId);if(!NB(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${x0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{let J=this.currentTokenSource();if(!J?.codexApiProvider&&!T9(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 i2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(H)=>Q.spawnEnv(H):void 0,...Q?.codexApiProvider?{apiProvider:Q.codexApiProvider}:{}}),V=null;try{Z=await Y.readConversationRef($.sessionId)}catch(H){V=H,Z=$}let X=null;try{await Y.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${x(V)}; cleanup=${x(X)}`);if(V)throw V;if(X)throw X}return U0({kind:"resume",source:Z},this.selectedProvider,this.workDir),O9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...R$.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 W$(this.selectedEffort)?this.selectedEffort:Y9}return Y9}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&A0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=k$($,this.selectedModel??$.defaultModel);if(!A0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return B1}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??k$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?B1:Y9)}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"?B1:Y9);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 K0($,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 gJ($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return c0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(U0($.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=PY(32).toString("base64url");let Z={LODESTAR_AGENT_URL:F6(p.notify.bind,p.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"});U0(J,this.selectedProvider,this.workDir);let Q=this.currentTokenSource(),Y=this.selectedProvider==="codex"&&this.selectedTokenSourceId==="codex-sub";if(this.selectedTokenSourceId&&(!Q||!Q.enabled&&!Y))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let V=Q?.enabled||Y?Q:void 0,X=this.currentTurn?.fileDeliveryMode??this.getFileDeliveryMode(),H=u9({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:U9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x2},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),this.procFileDeliveryModes.set(H.process,X),H.process}async applyModelSelection($,Z,J,Q){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Q))}async applyModelSelectionUnlocked($,Z,J,Q){let Y=this.selectedProvider,V=Q??this.selectedTokenSourceId,X=E0(V),H=X?Z||null:$==="codex"?null:Z,z=X?J??k$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,H,z);let G=Y!==$?{anchors:z4(this.sessionName).slice(),base:G4(this.sessionName),pending:W4(this.sessionName)}:null;if(G)J$(this.sessionName,[],null,null);try{R1(this.sessionName,$,H,z,V)}catch(W){if(G)try{J$(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=H,this.selectedEffort=z,this.lastSessionRef=A1(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()===s2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===s2($,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 H=this.finishProcStop(Y,X);this.opts.onLifecycleChange?.();let z=[...X?[X]:!H?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...V?[Error(V)]:[]];if(z.length===1)throw z[0];if(z.length>1)throw AggregateError(z,`idle process stop failed: ${z.map(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,H=!1,z=!1,G=null,W=()=>{if(V)return;if(X){z=!0;return}X=!0,z=!1;let _=Y;this.replaceFooterContent($,J(EB(Y,Q))).then((j)=>{if(X=!1,V)return;if(j.landed){if(z)W();return}if(H=!0,G)clearTimeout(G);if(G=null,z&&Y!==_)W()})},K=()=>{if(V||H)return;let{nextDelayMs:_}=N4(Date.now()-Q,P7());G=setTimeout(()=>{W(),K()},Math.max(1,Math.ceil(_)))};return W(),K(),{setStatus(_){if(_===Y)return;Y=_,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:EB(Z,Q),template:J}),V,X=await i(this.chatId,Y,(z)=>{V=z});if(!X)return B(`session "${this.sessionName}": status card send failed title=${$}`),await g(this.chatId,`❌ 创建状态卡片失败: ${$}
269
+ ${k(z)}`)}async function DB($,Z){if(!Z){await b($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await b($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=KB(j7($));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{BB(J)}if(!Q.ok){await b($.chatId,`❌ 建临时会话失败: ${Q.error??"未知"}`);return}await b($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function FB($){if(!r$($.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 MB($,Z,J,Q){let Y=LY($,"fork",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let H=KB(V.baseName);B(`session-temp: fork ${$.sessionName} → ${H} (${X.launch.kind})`),await b($.chatId,`\uD83D\uDD31 正在分叉到 ${H}…`);let z;try{z=await $.opts.onCreateTempSession({chatName:H,userOpenId:Q,workDir:V.workDir,routing:V.routing,launch:X.launch,branchBase:X.branchBase,seedAnchors:X.seedAnchors})}finally{BB(H)}if(!z.ok)return{ok:!1,message:`分叉失败: ${z.error??"未知"}`};return{ok:!0,message:`已分叉到 ${H};原会话和磁盘文件未回滚`}}catch(H){return{ok:!1,message:`分叉失败: ${H instanceof Error?H.message:H}`}}finally{_7(V)}}async function UB($,Z,J,Q){let Y=LY($,"back",Z,J,Q);if("error"in Y)return{ok:!1,message:Y.error,replaceCard:!1};let{panel:V,choice:X}=Y;try{if(X.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let H="";try{let W;if(!await i($.chatId,PQ({projectName:V.baseName,entries:X.writes}),(_)=>{W=_}))H=`;文件变更记录卡发送失败: ${k(W)}`}catch(W){H=`;文件变更记录卡发送失败: ${k(W)}`}if(B(`session-temp: back ${$.sessionName} (${X.launch.kind}, writes=${X.writes.length})`),!await $.rollbackTo(X.launch,{anchors:X.seedAnchors,base:X.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${H}`};if(V.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${H}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${x0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${H}`}}catch(H){return{ok:!1,message:`回退失败: ${H instanceof Error?H.message:H}`}}finally{_7(V)}}async function OB($,Z,J,Q){let Y=LY($,"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 _7(V),Error("resume panel contained a non-resume choice");let H=X.launch.source.sessionId,z=$.lastSessionId,G=(K,_)=>({projectName:V.baseName,provider:X.launch.source.provider,selectedPreview:X.sourcePreview,selectedTs:X.sourceTs,sourceSessionId:H,...X.sourceStatus?{sourceStatus:X.sourceStatus}:{},previousSessionId:z,newSessionId:K,bindingState:_}),W=(K,_,j,L=null)=>({ok:K,message:_,resumePresentation:G(L,j)});try{if($.isRunning())return W(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(X.sourceStatus==="active")return W(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(B(`session-temp: history fork ${$.sessionName} ← ${X.launch.source.provider} ${H}`),!await $.rollbackTo(X.launch,{anchors:[],base:X.launch,pendingLaunch:X.launch.source.provider==="claude"?{launch:X.launch,previousSessionId:z}:null}))return W(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(X.launch.source.provider==="claude")return W(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let _=$.lastSessionId;if(!_)return W(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(_===H||z&&_===z)return W(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",_);return W(!0,"已创建并接入独立分支;源会话未修改","changed",_)}catch(K){return W(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{_7(V)}}var fA=86400000,hA=1800000,IA=3600000,gA=40,WB,jY;var AB=R(()=>{e();L$();I();e2();Z9();u1();WB=new WeakMap,jY=new Set});import{existsSync as NB}from"node:fs";import{randomBytes as PY,timingSafeEqual as oA}from"node:crypto";import{isAbsolute as sA}from"node:path";function FY($,Z=new Set){if($ instanceof d2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Q=FY(J,Z);if(Q)return Q}if($ instanceof Error&&$.cause!==void 0)return FY($.cause,Z);return null}function tA($){return $.itemId||$.turnId||"__latest__"}function RB($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function rA($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function eA($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function P7(){return p.runtime?.live_elapsed??"bucket"}function EB($,Z){return`${$} (${N4(Date.now()-Z,P7()).label})`}function v4($){return $.length?$.map((Z)=>`${Z.operation}: ${k(Z)}`).join(`
270
+ `):k(void 0)}function YN($,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 TB="Thinking...",$N="Writing...",ZN="Working...",DY=1e4,q7=720000,JN=50,QN=256,L7=1e4,xB=250,R$;var QY=R(()=>{Z9();b9();B0();j1();SJ();B0();f0();yJ();wQ();Q0();D0();O4();e2();Z1();L$();e();I();V0();VQ();M$();TW();tZ();vQ();wW();iW();GK();Y7();BK();DJ();jK();AK();wK();cK();oK();tK();KY();GB();AB();u1();R$=class R${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=PY(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??RW(),R$.all.add(this);let Q=EZ($);this.selectedProvider=Q?.provider??"claude",this.selectedModel=Q?.model??null,this.selectedEffort=Q?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Q);let Y=E0(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=A1($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)B(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let V=W4($);if(V)if(this.selectedProvider!=="claude")J$($,[],null,null),B(`session "${$}": cleared pending Claude fork after provider changed`);else{M0(V.launch,"claude",this.workDir);let X=this.lastSessionId===V.previousSessionId,H=this.lastSessionRef,z=!X&&H?.provider==="claude"&&H.cwd===this.workDir&&H.sessionId!==V.launch.source.sessionId&&H.sessionId!==V.previousSessionId;if(!X&&!z)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=V,B(`session "${$}": restored ${z?"materialized":"pending"} Claude fork source=${V.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0,...this.proc?.isAlive()&&this.proc.provider==="codex"&&!this.currentTokenSource()?.codexApiProvider&&this.proc.codexAccountSelectionMode?.()!==null&&!(this.proc.turnRetry?.reason==="quota"&&this.proc.turnRetry.phase==="waiting")?{codexAccountName:v.get(G$(this.proc)).name}:{}}}get workDir(){return JB(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 v5(J)[0]?.id??null}currentTokenSource(){return this.tokenSource(this.selectedTokenSourceId)}codexStartAccountOverride;codexAccountId(){return this.proc?.isAlive()&&this.proc.provider==="codex"?G$(this.proc):this.codexStartAccountOverride??v.selected(this.sessionName)}tokenSource($){let Z=E0($);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()},...!$&&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=E0($.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)J$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;if(this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=A1(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,R1(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId),!Z?.codexApiProvider){let J=$.codexAccountId??c;if($.codexAccountAutomatic)v.selectAuto(this.sessionName);else if(v.selected(this.sessionName)!==J)v.select(this.sessionName,J)}}dshEffortForSpawn(){if(F0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource(),Z=$&&k$($,this.selectedModel??$.defaultModel);if(!Z||!F0(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 P4({cwd:this.workDir,env:$.spawnEnv(process.env),profile:{loadProjectMcp:!1}},"session/list",{cwd:this.workDir})).filter((J)=>!u2("dsh",J.sessionId))}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");let $=this.currentTokenSource();if(!$?.codexApiProvider&&!T9(this.codexAccountId()))throw Error("Codex 未登录 ChatGPT 账号");if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(H)=>Z.spawnEnv(H):void 0,Q=new i2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J,...Z?.codexApiProvider?{apiProvider:Z.codexApiProvider}:{}}),Y=null,V=null;try{Y=await Q.listConversations()}catch(H){V=H}let X=null;try{await Q.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex history query and cleanup failed: ${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=D8(this.workDir,$.sessionId);if(!NB(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${x0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{let J=this.currentTokenSource();if(!J?.codexApiProvider&&!T9(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 i2({workDir:this.workDir,codexAccountId:this.codexAccountId(),launch:{kind:"fresh"},tokenSourceId:Q?.id??null,transformEnv:Q?(H)=>Q.spawnEnv(H):void 0,...Q?.codexApiProvider?{apiProvider:Q.codexApiProvider}:{}}),V=null;try{Z=await Y.readConversationRef($.sessionId)}catch(H){V=H,Z=$}let X=null;try{await Y.kill(2000)}catch(H){X=H}if(V&&X)throw AggregateError([V,X],`Codex legacy resume lookup and cleanup failed: read=${x(V)}; cleanup=${x(X)}`);if(V)throw V;if(X)throw X}return M0({kind:"resume",source:Z},this.selectedProvider,this.workDir),O9(this.sessionName,Z),Z}hasRunningPeerSession($){return[...R$.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 W$(this.selectedEffort)?this.selectedEffort:Y9}return Y9}claudeEffortForSpawn(){if(this.selectedProvider==="claude"&&A0(this.selectedEffort))return this.selectedEffort;let $=this.currentTokenSource();if(this.selectedProvider==="claude"&&$?.agent==="claude"){let Z=k$($,this.selectedModel??$.defaultModel);if(!A0(Z?.defaultEffort))throw Error("Claude 默认 effort MISS,请通过 model 面板明确选择");return Z.defaultEffort}return B1}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??k$($,this.selectedModel??$.defaultModel)?.defaultEffort??null;return this.selectedEffort??(this.selectedProvider==="dsh"?this.dshEffortForSpawn():void 0)??this.proc?.lastEffort??(this.selectedProvider==="claude"?B1:Y9)}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"?B1:Y9);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 K0($,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 gJ($.provider,$.model,$.effort)}backendLabel($=this.selectedProvider){return c0($)}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=PY(32).toString("base64url");let Z={LODESTAR_AGENT_URL:F6(p.notify.bind,p.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(),H=u9({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:M9(this.workDir),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x2},hostEnv:Z});return this.procSourceRevisions.set(H.process,H.sourceRevision),this.procFileDeliveryModes.set(H.process,X),H.process}async applyModelSelection($,Z,J,Q){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Q))}async applyModelSelectionUnlocked($,Z,J,Q){let Y=this.selectedProvider,V=Q??this.selectedTokenSourceId,X=E0(V),H=X?Z||null:$==="codex"?null:Z,z=X?J??k$(X,Z||X.defaultModel)?.defaultEffort??null:$==="codex"?null:J;await this.stopIdleMismatchedProcessUnlocked($,V,H,z);let G=Y!==$?{anchors:z4(this.sessionName).slice(),base:G4(this.sessionName),pending:W4(this.sessionName)}:null;if(G)J$(this.sessionName,[],null,null);try{R1(this.sessionName,$,H,z,V)}catch(W){if(G)try{J$(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=H,this.selectedEffort=z,this.lastSessionRef=A1(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()===s2($,Z);return!this.proc||!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===s2($,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 H=this.finishProcStop(Y,X);this.opts.onLifecycleChange?.();let z=[...X?[X]:!H?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...V?[Error(V)]:[]];if(z.length===1)throw z[0];if(z.length>1)throw AggregateError(z,`idle process stop failed: ${z.map(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,H=!1,z=!1,G=null,W=()=>{if(V)return;if(X){z=!0;return}X=!0,z=!1;let _=Y;this.replaceFooterContent($,J(EB(Y,Q))).then((j)=>{if(X=!1,V)return;if(j.landed){if(z)W();return}if(H=!0,G)clearTimeout(G);if(G=null,z&&Y!==_)W()})},K=()=>{if(V||H)return;let{nextDelayMs:_}=N4(Date.now()-Q,P7());G=setTimeout(()=>{W(),K()},Math.max(1,Math.ceil(_)))};return W(),K(),{setStatus(_){if(_===Y)return;Y=_,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:EB(Z,Q),template:J}),V,X=await i(this.chatId,Y,(z)=>{V=z});if(!X)return B(`session "${this.sessionName}": status card send failed title=${$}`),await g(this.chatId,`❌ 创建状态卡片失败: ${$}
271
271
  ${k(V)}`),null;let H;try{H=await h$(X)}catch(z){return B(`session "${this.sessionName}": status card id_convert failed title=${$}: ${z}`),await g(this.chatId,`❌ 状态卡片初始化失败: ${$}
272
272
  ${k(z)}`),null}return A$(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(z)=>Z3($,z))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Q=Z3($.title,`${Z} (${R0(J)})`);await T1($.cardId);let Y=[],V=(z)=>{Y.push(z)},X=await K0($.cardId,C.footer,this.footerElement(Q),{onFailure:V});i0($.cardId);let H=await C0($.cardId,_2({durationSec:J,suffix:Z}),V);if(X&&H)await B$($.cardId);else{let z=`footer=${X?"ok":"MISS"}, settings=${H?"ok":"MISS"}`;B(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${z}`),await g(this.chatId,`⚠️ 状态卡片终态写入失败 (${z}):${Z}
273
273
  ${v4(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&&oA(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,J$(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;J$(this.sessionName,[],null,null),R1(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=A1(this.sessionName,"codex"),this.lastSessionId=this.lastSessionRef?.sessionId??null}if(this.selectedTokenSourceId!=="codex-sub")R1(this.sessionName,"codex",this.selectedModel,this.selectedEffort,"codex-sub"),this.selectedTokenSourceId="codex-sub";this.codexStartAccountOverride=$;try{if(this.proc?.isAlive()&&this.proc.provider==="codex"&&G$(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&&!T9(this.codexAccountId())){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z){let W;if(!await i(this.chatId,m$({phase:"warning",title:"需要登录",hint:"默认:codex-login · 额外:codex-login 备注"}),(_)=>{W=_}))throw Error(`Codex 登录引导卡片发送失败:${k(W)}`)}return!1}if(!NB(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await b(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{gZ(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,xB):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${V} 启动`:`⏳ 等待 ${V} init`);let H,z=null;try{Y.sendInitialize(),H=Y.initializationPromise?.()}catch(W){H=void 0,z=W}let G=z?{state:"error",error:z}:this.selectedProvider==="claude"?await X:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(H),()=>{B(`session "${this.sessionName}": codex init still pending after ${DY/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 _=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,j=`❌ ${V} 启动失败: ${W}${_}`;if(J?.(j),Z)await b(this.chatId,j);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(G.state==="timeout"){B(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${q7/1000}s)`);let K=await this.stopOwnedProc(Y,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,_=`❌ ${V} 启动超时: ${q7/1000} 秒内初始化事务未完成${K}`;if(J?.(_),Z)await b(this.chatId,_);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 i(this.chatId,m$({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(`
274
- `))}return this.status="idle",this.startedAt=Date.now(),this.daemonRestoreRequired=!1,this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Q=!1,Y=(H,z)=>{if(Q)return;Q=!0,clearTimeout(V),clearTimeout(X),J({state:H,error:z})},V=setTimeout(()=>{if(Q)return;try{Z?.()}catch(H){Y("error",H)}},DY),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${q7/1000}s`))},q7);$.then(()=>Y("init"),(H)=>Y("error",H)),this.proc?.quotaWaitPromise?.().then(()=>Y("waiting_quota"),(H)=>Y("error",H))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(G,W)=>{if(Q)return;Q=!0,clearTimeout(V),$.off("init",X),$.off("error",H),$.off("exit",z),J({state:G,error:W})},V=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),H=(G)=>Y("error",G),z=(G)=>Y("exit",G);$.once("init",X),$.once("error",H),$.once("exit",z)})}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),H=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 z=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){H=`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 _=Y.conversationMaterializationFailure?.();if(_&&Y.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${x(_)}`;X=this.persistResumableSessionId(!1,Y,!1);let L=(await Promise.allSettled([this.resetBackgroundTasks(),z])).filter((F)=>F.status==="rejected").map((F)=>F.reason);for(let F of L)B(`session "${this.sessionName}": stop terminal cleanup failed: ${x(F)}`);let q=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 D=[...V?[V]:[],...K?[K]:[],...!q&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...L,...G,...X?[Error(X)]:[],...H&&Y.isConversationResumable?.()!==!0?[Error(H)]:[]];if(D.length===1)throw D[0];if(D.length>1)throw AggregateError(D,`stop failed: ${D.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,N1(this.sessionName,null),this.pendingConversationMaterialization=null;let H=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!H&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(E){let m=this.invalidateMissingCodexResume(z.sessionId,E,J),Y0=m?`❌ 旧会话不可恢复: ${x(E)};${m}`:`❌ 旧会话 cwd 校验失败: ${x(E)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Y?.(Y0),Q)await b(this.chatId,Y0);return!1}let G=z?.sessionId??null,W=H&&H.kind!=="fresh"?H.source.sessionId:G,K=W?x0(W):"",_=null,j=(E=this.proc)=>{if(!$||H||E?.provider!=="codex"||E.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,E,!1),z=this.lastSessionRef,G=z?.sessionId??null,W=G,K=W?x0(W):""},L=null;if(!Y&&Q&&$&&G){let E=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(L=await this.openStatusCard("restart",E),L)Y=(m)=>this.setStatusCard(L,m)}let q=Q&&!L,D=async(E)=>{if(L)await this.closeStatusCard(L,E)},F=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||MJ(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let E of this.fileDeliveries)E.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((E)=>{B(`session "${this.sessionName}": restart current main-card close failed: ${x(E)}`)});let U=this.waitForTurnCloses().catch((E)=>B(`session "${this.sessionName}": restart main-card close failed: ${x(E)}`)),M=null,O=null,A=null;if(this.proc){let E=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(E.provider)}`),A=E;let m=this.agentCapability;this.beginProcStop(E);try{await this.cancelAgentRuns("会话正在重启")}catch(N){O=N}let Y0=E.conversationMaterializationBarrier?.();if(Y0)try{await Y0}catch(N){_=`Codex 会话落盘确认失败: ${x(N)}`}if(j(E),$&&!H&&_&&!O&&!F&&E.isAlive()){if(this.proc===E&&this.stoppingProc===E)this.stoppingProc=null,this.agentCapability=m;this.status=V;let N=`❌ ${this.backendLabel(E.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(B(`session "${this.sessionName}": abort restart before kill: ${_}`),Y?.(N),q)await b(this.chatId,N);return await D(N),!1}try{await E.kill()}catch(N){M=N}let w=E.conversationMaterializationFailure?.();if(w&&E.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${x(w)}`;j(E)}else try{await this.cancelAgentRuns("会话正在重启")}catch(E){O=E}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let y=(await Promise.allSettled([this.resetBackgroundTasks(),U])).filter((E)=>E.status==="rejected").map((E)=>E.reason);for(let E of y)B(`session "${this.sessionName}": restart terminal cleanup failed: ${x(E)}`);let S=A?this.finishProcStop(A,M):!0,h=[...O?[`agents=${x(O)}`]:[],...M?[`kill=${x(M)}`]:[],...!S&&!M?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...y.map((E)=>`cleanup=${x(E)}`),..._?[`resume=${_}`]:[]];if(h.length>0&&X)try{N1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(E){h.push(`pendingRestore=${x(E)}`)}if(h.length>0){let E=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${h.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(E),q)await b(this.chatId,E);return await D(E),!1}let l=H?.kind==="resume"||H?.kind==="fork";if($&&z||l){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let E;try{E=this.spawnAgent(z??void 0)}catch(n){let T0=`❌ ${this.backendLabel()} 恢复失败: ${x(n)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${x(n)}`),Y?.(T0),q)await b(this.chatId,T0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(T0),!1}this.attachProc(E);let m=this.backendLabel(),Y0=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(E,xB):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${m} 恢复启动`:`⏳ 等待 ${m} init 确认`);let w,N=null;try{E.sendInitialize(),w=E.initializationPromise?.()}catch(n){w=void 0,N=n}let f=N?{state:"error",error:N}:this.selectedProvider==="claude"?await Y0:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(w),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${DY/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${m} init 确认 thread=${K}`))});if(f.state==="error"||f.state==="exit"||f.state==="timeout"){let n=f.state==="error"?this.invalidateMissingCodexResume(W,f.error,J):null,T0=[f.error?x(f.error):f.state,n].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${T0}`);let c4=await this.stopOwnedProc(E,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,D$=f.state==="timeout"?`❌ ${m} 恢复超时${c4}`:`❌ ${m} 恢复失败: ${T0}${c4}`;if(Y?.(D$),q)await b(this.chatId,D$);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(D$),!1}if(this.proc!==E||!E.isAlive()){let n=`❌ ${m} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(n),q)await b(this.chatId,n);return this.detachProc(E),this.status="stopped",this.opts.onLifecycleChange?.(),await D(n),!1}let z0=this.withModel(this.withWorktreeInstructionNotice(f.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&f.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Y?.(z0),q)await b(this.chatId,z0);if(this.status=f.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),f.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await D(z0)}catch(n){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${x(n)}`),await g(this.chatId,`⚠️ ${z0}
275
- 状态卡收尾失败: ${x(n)}`)}return!0}else{if($&&!H){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),q)await b(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{U0($,this.selectedProvider,this.workDir);let J=W4(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)N1(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)N1(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{N1(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()=>{U0($,this.selectedProvider,this.workDir);let Q=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Y=this.proc,V=this.lastSessionId,X=this.lastSessionRef,H=z4(this.sessionName).slice(),z=G4(this.sessionName),G=W4(this.sessionName),W={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,_=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,H4(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)O9(this.sessionName,X);else H4(this.sessionName,this.selectedProvider);J$(this.sessionName,H,z,G),this.pendingConversationMaterialization=G,this.turnCounter=W.turnCounter,this.currentGoal=W.currentGoal,this.cumStats=W.cumStats,this.lastTurnDelta=W.lastTurnDelta,this.currentTurnUsageBaseline=W.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=W.currentTurnUsageBaselineKnown,this.lastTurnUsage=W.lastTurnUsage,this.usageTotalsSeedUnknown=W.usageTotalsSeedUnknown},j=!1;if(Q?.pendingLaunch)J$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,j=!0;this.pendingConversationLaunch=$;let L=(q)=>{K=X?.provider==="codex"&&X.sessionId===q};try{let q;try{q=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(D){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 M=!U||this.proc!==U&&!U.isAlive();if(!M&&!F)F=Error("replacement process stop was not confirmed");let O=null;if(M)try{_()}catch(T){O=T}let A=[D,...F?[F]:[],...O?[O]:[]];if(A.length===1)throw D;throw AggregateError(A,`rollback launch and cleanup failed: ${A.map(x).join("; ")}`)}if(!q)return _(),!1;if(Q)try{if(!j)J$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(D){let F=null,U=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(T){F=T}let M=!U||this.proc!==U&&!U.isAlive();if(!M&&!F)F=Error("replacement process stop was not confirmed");let O=null;if(M)try{_()}catch(T){O=T}let A=[D,...F?[F]:[],...O?[O]:[]];if(A.length===1)throw D;throw AggregateError(A,`rollback branch commit failed: ${A.map(x).join("; ")}`)}return q}finally{this.pendingConversationLaunch=null}})}dispose(){R$.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 RZ(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(...UQ(J.name,J.input));return Z}worktreeProjectName(){return O2(this)}worktreeProjectDir(){return w4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return QB(this,$)}delegatedAgentDeveloperInstructions($){return YB(this,$)}worktreeInstructionLoadedNotice(){return BY(this)}withWorktreeInstructionNotice($){return VB(this,$)}worktreeExtraInstruction(){return F3(this)}runWorktreeCommand($,Z){return XB(this,$,Z)}showWorktrees(){return _Y(this)}showTasklistPanel(){return IK(this)}showAgentIdentityPanel($=""){return SK(this,$)}onAgentIdentityPage($,Z,J){return CK($,Z,J)}onTasklistEnable(){return gK(this)}onTasklistDeletePrompt($){return mK(this,$)}onTasklistDeleteConfirm($){return pK(this,$)}runCompactCommand(){return _K(this)}showModelPanel(){return LK(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>rQ(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 g(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Q=null){return this.runLifecycle("model-select",()=>OK(this,$,Z,J,Q))}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>JY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return $Y(this,$,Z)}onModelPage($,Z,J){return X7(this,$,Z,J)}onModelAddOpen($,Z){return PK(this,$,Z)}onModelListEdit($,Z,J,Q){return this.runLifecycle("model-list-edit",()=>DK(this,$,Z,J,Q))}onModelPanelCancel($=""){return MK(this,$)}onModelCustomPrompt($,Z,J=""){return FK(this,$,Z,J)}consumeModelCustomMessage($,Z){return UK(this,$,Z)}onWorktreeDisband($){return zB(this,$)}showForkList($=""){return qB(this,$)}showBackList($=""){return LB(this,$)}showResumeList($=""){return PB(this,$)}runBtwCommand($){return DB(this,$)}runByeCommand(){return FB(this)}onForkSelect($,Z,J=""){return UB(this,$,Z,J)}onBackSelect($,Z,J=""){return MB(this,$,Z,J)}onResumeSelect($,Z,J=""){return OB(this,$,Z,J)}runCommand($,Z="",J){return QG(this,$,Z,J)}getFileDeliveryMode(){return k4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return sK(this.chatId,this.sessionName,Z,$,{get:(J)=>k4.get(J,this.workDir),enable:(J,Q)=>k4.enable(J,this.workDir,Q),disable:(J)=>k4.disable(J,this.workDir),sendCard:(J,Q)=>i(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 ZW(),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:[...R$.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,accountUsages:await yQ(),sysinfo:J}}async buildConsoleCard($){return l6(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await yQ()}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 K0($,C.consoleUsage,J3(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}))throw Error(`console usage element replace rejected: ${k(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 C0($,{config:{streaming_mode:!1}},(X)=>{Y.push(k(X))})}catch(X){Y.push(k(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 g(this.chatId,`⚠️ 卡片更新失败 (${Z})。
274
+ `))}return this.status="idle",this.startedAt=Date.now(),this.daemonRestoreRequired=!1,this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Q=!1,Y=(H,z)=>{if(Q)return;Q=!0,clearTimeout(V),clearTimeout(X),J({state:H,error:z})},V=setTimeout(()=>{if(Q)return;try{Z?.()}catch(H){Y("error",H)}},DY),X=setTimeout(()=>{Y("timeout",Error(`codex init timed out after ${q7/1000}s`))},q7);$.then(()=>Y("init"),(H)=>Y("error",H)),this.proc?.quotaWaitPromise?.().then(()=>Y("waiting_quota"),(H)=>Y("error",H))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Q=!1,Y=(G,W)=>{if(Q)return;Q=!0,clearTimeout(V),$.off("init",X),$.off("error",H),$.off("exit",z),J({state:G,error:W})},V=setTimeout(()=>Y("ready"),Z),X=()=>Y("init"),H=(G)=>Y("error",G),z=(G)=>Y("exit",G);$.once("init",X),$.once("error",H),$.once("exit",z)})}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),H=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 z=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){H=`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 _=Y.conversationMaterializationFailure?.();if(_&&Y.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${x(_)}`;X=this.persistResumableSessionId(!1,Y,!1);let L=(await Promise.allSettled([this.resetBackgroundTasks(),z])).filter((F)=>F.status==="rejected").map((F)=>F.reason);for(let F of L)B(`session "${this.sessionName}": stop terminal cleanup failed: ${x(F)}`);let q=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 D=[...V?[V]:[],...K?[K]:[],...!q&&!K?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...L,...G,...X?[Error(X)]:[],...H&&Y.isConversationResumable?.()!==!0?[Error(H)]:[]];if(D.length===1)throw D[0];if(D.length>1)throw AggregateError(D,`stop failed: ${D.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,N1(this.sessionName,null),this.pendingConversationMaterialization=null;let H=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),z=this.lastSessionRef;if($&&!H&&z?.cwd===null)try{z=await this.resolveLegacyResumeRef(z),this.lastSessionRef=z,this.lastSessionId=z.sessionId}catch(E){let m=this.invalidateMissingCodexResume(z.sessionId,E,J),Y0=m?`❌ 旧会话不可恢复: ${x(E)};${m}`:`❌ 旧会话 cwd 校验失败: ${x(E)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?V:"stopped",Y?.(Y0),Q)await b(this.chatId,Y0);return!1}let G=z?.sessionId??null,W=H&&H.kind!=="fresh"?H.source.sessionId:G,K=W?x0(W):"",_=null,j=(E=this.proc)=>{if(!$||H||E?.provider!=="codex"||E.isConversationResumable?.()!==!0)return;_=this.persistResumableSessionId(!1,E,!1),z=this.lastSessionRef,G=z?.sessionId??null,W=G,K=W?x0(W):""},L=null;if(!Y&&Q&&$&&G){let E=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(L=await this.openStatusCard("restart",E),L)Y=(m)=>this.setStatusCard(L,m)}let q=Q&&!L,D=async(E)=>{if(L)await this.closeStatusCard(L,E)},F=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||UJ(this.backgroundTasks)||this.pendingBgTasks.length>0||this.backgroundSync);this.bgResumePending=!1,this.invalidateTurnOpen(),this.discardOrphanAssistant();for(let E of this.fileDeliveries)E.cancel("会话正在重启");if(this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((E)=>{B(`session "${this.sessionName}": restart current main-card close failed: ${x(E)}`)});let M=this.waitForTurnCloses().catch((E)=>B(`session "${this.sessionName}": restart main-card close failed: ${x(E)}`)),U=null,O=null,A=null;if(this.proc){let E=this.proc;Y?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(E.provider)}`),A=E;let m=this.agentCapability;this.beginProcStop(E);try{await this.cancelAgentRuns("会话正在重启")}catch(N){O=N}let Y0=E.conversationMaterializationBarrier?.();if(Y0)try{await Y0}catch(N){_=`Codex 会话落盘确认失败: ${x(N)}`}if(j(E),$&&!H&&_&&!O&&!F&&E.isAlive()){if(this.proc===E&&this.stoppingProc===E)this.stoppingProc=null,this.agentCapability=m;this.status=V;let N=`❌ ${this.backendLabel(E.provider)} 恢复点尚未安全落盘,已保留当前进程: ${_}`;if(B(`session "${this.sessionName}": abort restart before kill: ${_}`),Y?.(N),q)await b(this.chatId,N);return await D(N),!1}try{await E.kill()}catch(N){U=N}let w=E.conversationMaterializationFailure?.();if(w&&E.isConversationResumable?.()!==!0)_=`Codex 会话落盘确认失败: ${x(w)}`;j(E)}else try{await this.cancelAgentRuns("会话正在重启")}catch(E){O=E}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let y=(await Promise.allSettled([this.resetBackgroundTasks(),M])).filter((E)=>E.status==="rejected").map((E)=>E.reason);for(let E of y)B(`session "${this.sessionName}": restart terminal cleanup failed: ${x(E)}`);let S=A?this.finishProcStop(A,U):!0,h=[...O?[`agents=${x(O)}`]:[],...U?[`kill=${x(U)}`]:[],...!S&&!U?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...y.map((E)=>`cleanup=${x(E)}`),..._?[`resume=${_}`]:[]];if(h.length>0&&X)try{N1(this.sessionName,X),this.pendingConversationMaterialization=X}catch(E){h.push(`pendingRestore=${x(E)}`)}if(h.length>0){let E=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${h.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.(E),q)await b(this.chatId,E);return await D(E),!1}let l=H?.kind==="resume"||H?.kind==="fork";if($&&z||l){this.status="starting",this.usageTotalsSeedUnknown=!0,Y?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let E;try{E=this.spawnAgent(z??void 0)}catch(n){let T0=`❌ ${this.backendLabel()} 恢复失败: ${x(n)}`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${x(n)}`),Y?.(T0),q)await b(this.chatId,T0);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(T0),!1}this.attachProc(E);let m=this.backendLabel(),Y0=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(E,xB):null;Y?.(this.selectedProvider==="claude"?`⏳ 检查 ${m} 恢复启动`:`⏳ 等待 ${m} init 确认`);let w,N=null;try{E.sendInitialize(),w=E.initializationPromise?.()}catch(n){w=void 0,N=n}let f=N?{state:"error",error:N}:this.selectedProvider==="claude"?await Y0:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(w),()=>{B(`session "${this.sessionName}": codex resume init still pending after ${DY/1000}s`),Y?.(this.withModel(`⏳ 仍在等待 ${m} init 确认 thread=${K}`))});if(f.state==="error"||f.state==="exit"||f.state==="timeout"){let n=f.state==="error"?this.invalidateMissingCodexResume(W,f.error,J):null,T0=[f.error?x(f.error):f.state,n].filter(Boolean).join(";");B(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${T0}`);let c4=await this.stopOwnedProc(E,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,D$=f.state==="timeout"?`❌ ${m} 恢复超时${c4}`:`❌ ${m} 恢复失败: ${T0}${c4}`;if(Y?.(D$),q)await b(this.chatId,D$);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(D$),!1}if(this.proc!==E||!E.isAlive()){let n=`❌ ${m} 恢复期间已退出`;if(B(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Y?.(n),q)await b(this.chatId,n);return this.detachProc(E),this.status="stopped",this.opts.onLifecycleChange?.(),await D(n),!1}let z0=this.withModel(this.withWorktreeInstructionNotice(f.state==="waiting_quota"?"⏳ 账号额度用尽 · 等待后自动恢复原会话":this.selectedProvider==="claude"&&f.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Y?.(z0),q)await b(this.chatId,z0);if(this.status=f.state==="waiting_quota"?"starting":"idle",this.startedAt=Date.now(),f.state!=="waiting_quota")this.daemonRestoreRequired=!1;this.opts.onLifecycleChange?.();try{await D(z0)}catch(n){B(`session "${this.sessionName}": restart succeeded but status-card close failed: ${x(n)}`),await g(this.chatId,`⚠️ ${z0}
275
+ 状态卡收尾失败: ${x(n)}`)}return!0}else{if($&&!H){if(Y?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),q)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=W4(this.sessionName),Q=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Q)N1(this.sessionName,Q),this.pendingConversationMaterialization=Q;this.pendingConversationLaunch=$;try{let Y=await this.startUnlocked(Z);if(!Y&&Q)N1(this.sessionName,J),this.pendingConversationMaterialization=J;return Y}catch(Y){if(!Q)throw Y;try{N1(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,H=z4(this.sessionName).slice(),z=G4(this.sessionName),G=W4(this.sessionName),W={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},K=!1,_=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,H4(this.sessionName,"codex");else if(this.lastSessionId=V,this.lastSessionRef=X,X)O9(this.sessionName,X);else H4(this.sessionName,this.selectedProvider);J$(this.sessionName,H,z,G),this.pendingConversationMaterialization=G,this.turnCounter=W.turnCounter,this.currentGoal=W.currentGoal,this.cumStats=W.cumStats,this.lastTurnDelta=W.lastTurnDelta,this.currentTurnUsageBaseline=W.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=W.currentTurnUsageBaselineKnown,this.lastTurnUsage=W.lastTurnUsage,this.usageTotalsSeedUnknown=W.usageTotalsSeedUnknown},j=!1;if(Q?.pendingLaunch)J$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch),this.pendingConversationMaterialization=Q.pendingLaunch,j=!0;this.pendingConversationLaunch=$;let L=(q)=>{K=X?.provider==="codex"&&X.sessionId===q};try{let q;try{q=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(D){let F=null,M=this.proc&&this.proc!==Y?this.proc:null;if(M)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(T){F=T}let U=!M||this.proc!==M&&!M.isAlive();if(!U&&!F)F=Error("replacement process stop was not confirmed");let O=null;if(U)try{_()}catch(T){O=T}let A=[D,...F?[F]:[],...O?[O]:[]];if(A.length===1)throw D;throw AggregateError(A,`rollback launch and cleanup failed: ${A.map(x).join("; ")}`)}if(!q)return _(),!1;if(Q)try{if(!j)J$(this.sessionName,Q.anchors,Q.base,Q.pendingLaunch);this.pendingConversationMaterialization=Q.pendingLaunch}catch(D){let F=null,M=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(T){F=T}let U=!M||this.proc!==M&&!M.isAlive();if(!U&&!F)F=Error("replacement process stop was not confirmed");let O=null;if(U)try{_()}catch(T){O=T}let A=[D,...F?[F]:[],...O?[O]:[]];if(A.length===1)throw D;throw AggregateError(A,`rollback branch commit failed: ${A.map(x).join("; ")}`)}return q}finally{this.pendingConversationLaunch=null}})}dispose(){R$.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 RZ(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(...MQ(J.name,J.input));return Z}worktreeProjectName(){return O2(this)}worktreeProjectDir(){return w4(this)}spawnDeveloperInstructions($=this.getFileDeliveryMode()){return QB(this,$)}delegatedAgentDeveloperInstructions($){return YB(this,$)}worktreeInstructionLoadedNotice(){return BY(this)}withWorktreeInstructionNotice($){return VB(this,$)}worktreeExtraInstruction(){return F3(this)}runWorktreeCommand($,Z){return XB(this,$,Z)}showWorktrees(){return _Y(this)}showTasklistPanel(){return IK(this)}showAgentIdentityPanel($=""){return SK(this,$)}onAgentIdentityPage($,Z,J){return CK($,Z,J)}onTasklistEnable(){return gK(this)}onTasklistDeletePrompt($){return mK(this,$)}onTasklistDeleteConfirm($){return pK(this,$)}runCompactCommand(){return _K(this)}showModelPanel(){return LK(this)}finishModelSettingsChange($,Z){return this.runLifecycle("model-settings-complete",()=>rQ(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 g(this.chatId,`❌ ${Z}`)})}onModelSelect($,Z="",J="",Q=null){return this.runLifecycle("model-select",()=>OK(this,$,Z,J,Q))}onModelEffortSelect($,Z,J="",Q="",Y=""){return this.runLifecycle("model-effort-select",()=>JY(this,$,Z,J,Q,Y))}onProviderSelect($,Z=""){return $Y(this,$,Z)}onModelPage($,Z,J){return X7(this,$,Z,J)}onModelAddOpen($,Z){return PK(this,$,Z)}onModelListEdit($,Z,J,Q){return this.runLifecycle("model-list-edit",()=>DK(this,$,Z,J,Q))}onModelPanelCancel($=""){return UK(this,$)}onModelCustomPrompt($,Z,J=""){return FK(this,$,Z,J)}consumeModelCustomMessage($,Z){return MK(this,$,Z)}onWorktreeDisband($){return zB(this,$)}showForkList($=""){return qB(this,$)}showBackList($=""){return LB(this,$)}showResumeList($=""){return PB(this,$)}runBtwCommand($){return DB(this,$)}runByeCommand(){return FB(this)}onForkSelect($,Z,J=""){return MB(this,$,Z,J)}onBackSelect($,Z,J=""){return UB(this,$,Z,J)}onResumeSelect($,Z,J=""){return OB(this,$,Z,J)}runCommand($,Z="",J){return QG(this,$,Z,J)}getFileDeliveryMode(){return k4.mode(this.chatId,this.workDir)}runFileDeliveryCommand($,Z){return sK(this.chatId,this.sessionName,Z,$,{get:(J)=>k4.get(J,this.workDir),enable:(J,Q)=>k4.enable(J,this.workDir,Q),disable:(J)=>k4.disable(J,this.workDir),sendCard:(J,Q)=>i(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 ZW(),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:[...R$.all].filter((Y)=>Y.isRunning()).map((Y)=>({...Y.peerSnapshot(),isCurrent:Y===this})),usage:$,glmUsage:Z,accountUsages:await yQ(),sysinfo:J}}async buildConsoleCard($){return l6(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0);try{Z.accountUsages=await yQ()}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 K0($,C.consoleUsage,J3(Z),{notifyCardFailure:!1,onFailure:(Y)=>{J=Y}}))throw Error(`console usage element replace rejected: ${k(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 C0($,{config:{streaming_mode:!1}},(X)=>{Y.push(k(X))})}catch(X){Y.push(k(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 g(this.chatId,`⚠️ 卡片更新失败 (${Z})。
276
276
  ${Y.join(`
277
277
  `)||k(void 0)}`),!1;try{await B$($)}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 T1($.cardId);let Y=[],V=(K)=>{Y.push(K)},X=await K0($.cardId,C.footer,p6(Q,C.footer),{onFailure:V}),H=await X2($.cardId,m6(Q),{type:"insert_after",targetElementId:C.footer,onFailure:V}),z=await X2($.cardId,c6(Q.sysinfo),{type:"insert_after",targetElementId:C.consoleProjects,onFailure:V}),G=await X2($.cardId,J3(Q),{type:"insert_after",targetElementId:C.consoleHost,onFailure:V});if(!X||!H||!z||!G){await g(this.chatId,`⚠️ 控制台卡片结构写入失败,请重新发送 hi。
278
278
  ${v4(Y)}`),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}if(i0($.cardId),!await C0($.cardId,_2({durationSec:J,suffix:Z}),V))await g(this.chatId,`⚠️ 控制台卡片状态写入失败。
279
279
  ${v4(Y)}`);this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleOpts(void 0);await i(this.chatId,l6($))}interrupt(){if(!this.proc)return;B(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}disabledSubscriptionMessage($=this.selectedTokenSourceId){let Z=this.tokenSource($);return Z?.kind==="claude-subscription"&&!Z.enabled?Z.modelCatalogState?.error??"Claude Code 订阅未启用,请发送 claude-sub 查看状态":null}async sendClaimedUserText($,Z){let J=this.modelSettingsBlockReason();if(J)throw Error(J);let Q=this.disabledSubscriptionMessage($.tokenSourceId);if(Q){let z=`❌ ${Q}。消息未送给 Agent,请启用后重发或通过 md 切换来源。`;if(this.pendingTurnInputs=[],this.currentTurn)await this.closeTurnCard(z);else await b(this.chatId,z);return this.status="idle",!1}let Y=this.currentTurn,V=Y?Y.fileDeliveryMode??=this.getFileDeliveryMode():this.getFileDeliveryMode(),X=this.procFileDeliveryModes.get($),H=X===V?"":`${$B(V)}
280
280
 
281
281
  `;this.procFileDeliveryModes.set($,V),this.pendingUserMessageCount++;try{$.sendUserText(H+Z,[])}catch(z){if(this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),X===void 0)this.procFileDeliveryModes.delete($);else this.procFileDeliveryModes.set($,X);throw z}return!0}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Q=this.beginTurnOpen();try{let V=await this.openTurnCard(Q,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!V||this.currentTurn!==V)return;let X=this.startFooterTimer(V.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(W)=>this.withModel(W)),H=`\uD83D\uDE80 启动 ${this.backendLabel()}`,z=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(W)=>{H=W,X.setStatus(W)}});if(X.stop(),await T1(V.cardId),!z){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(H.startsWith("❌")?H:"❌ 启动失败",{forcePush:!0});return}let G=this.proc;if(!G?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}if(this.startThinkingFooter(V),!await this.sendClaimedUserText(G,Z))return;this.status="working"}finally{this.releaseTurnOpen(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 H=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let G=(Z.length?Z.map((K)=>`[file: ${K}]`).join(" ")+`
282
- `:"")+$,W=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let _=await Q$(K,"OneSecond");if(!_)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,_);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,_);else g0(K,_)})().catch((_)=>{B(`session "${this.sessionName}": reaction tracking failed: ${x(_)}`)})};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,_=this.procEpoch,j=this.beginTurnOpen(K,_);try{this.pendingTurnInputs.push($);let L=await this.openTurnCard(j,J,"user_message");if(!L||this.currentTurn!==L)return;if(this.proc!==K||this.procEpoch!==_||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,G))return;this.status="working"}finally{this.releaseTurnOpen(j)}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(H&&Q)W(Q)}hasPendingAsk(){return JK(this)}refreshPendingAsks(){Q7(this)}askBlockReason($){return C4(this,$)}onMultiMessageInbound($,Z,J,Q){return kW(this,$,Z,J,Q)}clearMultiMsgBuffer($){hQ(this,$)}onAskMessageAnswer($,Z,J){return QK(this,$,Z,J)}onAskAnswer($,Z,J,Q){return YK(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return nQ(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return WK(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=A1(this.sessionName,"codex");if(H4(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=FY(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=A1(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{H4(this.sessionName,"codex")}catch(X){let H=`已确认恢复点无 rollout,但作废失败: ${x(X)}`;return B(`session "${this.sessionName}": ${H} thread=${$}`),H}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${x0($)}`;return B(`session "${this.sessionName}": ${V} fullThread=${$}`),V}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Q=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Y=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Y){if(!Q)return null;let H=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}let V={provider:Z.provider,sessionId:Y,cwd:this.workDir};if(Q&&(Y===Q.launch.source.sessionId||Q.previousSessionId!==null&&Y===Q.previousSessionId)){let H=Error(`Claude fork did not materialize an independent session id (${Y})`);if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}try{O9(this.sessionName,V)}catch(H){let z=`会话恢复点持久化失败: ${x(H)}`,G=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;if(B(`session "${this.sessionName}": ${z}`),$)throw H;if(G&&J)g(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let H=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(H&&J)g(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 N1(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(NJ(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 g(this.chatId,`⚠️ 运行任务面板更新失败:${Z}`)}async resetBackgroundTasks(){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null;let $=Date.now();if(this.backgroundTasks=this.backgroundTasks.map((Z)=>_$(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=PY(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=(H,z)=>{$.on(H,(G)=>{if(!Q()){if(!Y)Y=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(H)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(H!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(H)} while process stop is pending`);return}z(G)})};X("error",(H)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${H}`)}),X("init",()=>{if($.provider==="codex"&&$.quotaWaitPromise){if(this.daemonRestoreRequired=!1,this.status==="starting")this.status=this.currentTurn?"working":"idle";this.opts.onLifecycleChange?.()}if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,B(`session "${this.sessionName}": SDK init#${this.initCount} pendingCount=${this.pendingUserMessageCount} midBuffer=${this.pendingMidTurnMsgs.length} currentTurn=${this.currentTurn?"yes":"no"} openingTurn=${this.openingTurn}`),this.currentTurn||this.openingTurn){if(this.pendingUserMessageCount>0)B(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let H=this.pendingUserMessageCount>0,z=!H&&this.bgResumePending;if(!H&&!z)return;let G=this.lastUserOpenId,W;try{W=this.beginTurnOpen($,J,!0)}catch(j){B(`session "${this.sessionName}": init turn-open ownership conflict: ${x(j)}`);return}if(this.bgResumePending=!1,H)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=H?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let j of K){let L=this.currentBatchReactionIds.get(j);if(this.currentBatchReactionIds.delete(j),L)g0(j,L)}};(async()=>{try{let j=await this.openTurnCard(W,G,H?"user_message":"bg_task_resume");if(!Q()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),j&&this.currentTurn===j)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!j||this.currentTurn!==j){if(!this.ownsTurnOpen(W)){_();return}if(W.sawResult&&W.terminalSuffix)g(this.chatId,W.terminalSuffix);if(H)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else B(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(W.terminalSuffix,{forcePush:W.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(W)}})().catch((j)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${x(j)}`)})}),X("scheduled_turn_input",({text:H,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,H,z)}),X("conversation_materialized",({session_id:H,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==H){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${H} current=${$.sessionId??"MISS"} source=${z}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${H} source=${z}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:H,source:z,error:G})=>{if($.provider!=="codex"||$.sessionId!==H)return;let W=`Codex 会话落盘确认失败,未写恢复点: ${x(G)}`,K=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,B(`session "${this.sessionName}": ${W} thread=${H} source=${z}`),K)g(this.chatId,`⚠️ ${W}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:H,diagnostics:z})=>{if(B(`session "${this.sessionName}": Codex account=${H}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)B(`session "${this.sessionName}": Codex 未参与选号的账号: ${z.join(";")}`)}),X("turn_started",({retry:H})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)B(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),H){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let z=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!z){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=z?{...z}:null,this.currentTurnUsageBaselineKnown=!0}),X("token_usage",({totalUsage:H})=>{if(this.persistResumableSessionId(),H)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(H)=>{this.handleTurnPlanUpdated(H)}),X("plan_delta",(H)=>{this.handlePlanDelta(H)}),X("context_compacted",(H)=>{this.handleContextCompacted(H)}),X("rate_limits_updated",(H)=>{if($.provider==="codex"&&!E0($.tokenSourceId)?.codexApiProvider)MX(H,G$($))}),X("thread_goal_updated",(H)=>{this.handleThreadGoalUpdated(H)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:H,parentToolUseId:z})=>{if(z)return;this.appendAssistant(H)}),X("assistant_block_stop",({parentToolUseId:H})=>{if(H)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:H,name:z,input:G,parentToolUseId:W})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(RJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}if(!W&&(z==="Task"||z==="Agent"||$.provider==="dsh"&&(z==="subagent"||z==="subagent_fork"))){let K=this.currentTurn;if(K)this.startWorkingFooter(K),this.finalizeCurrentAssistantSegment(),K.openBatchI=null,K.taskCreateI=null,K.taskUpdateI=null;if(this.onMainThreadAdvance(),this.nativeAgentTools.set(H,{confirmed:!1,input:G}),$.provider==="claude")this.lastMainTaskToolUseId=H,this.applyBgStore(c9(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:G?.description||G?.name||"子 Agent",prompt:G?.prompt,subagent_type:G?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(HK(this,H,z,G),!W)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:H,content:z,is_error:G,parentToolUseId:W,input:K})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(xJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}let _=!W&&this.nativeAgentTools.get(H);if(_){if(this.nativeAgentTools.delete(H),this.lastMainTaskToolUseId===H)this.lastMainTaskToolUseId=null;if(G||$.provider==="claude"&&!_.confirmed&&_.input?.run_in_background!==!0){let j=typeof z==="string"?z:Array.isArray(z)?z.map((q)=>typeof q?.text==="string"?q.text:JSON.stringify(q)).join(`
283
- `):JSON.stringify(z)??"MISS",L=this.backgroundTasks.find((q)=>q.toolUseId===H);if(!L)this.applyBgStore(c9(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:_.input?.description||"子 Agent",prompt:_.input?.prompt})),L=this.backgroundTasks.find((q)=>q.toolUseId===H);this.applyBgStore(L6(this.bgStore(),{task_id:L.id,status:G?"failed":"completed",summary:j})),this.onBackgroundTaskChanged(!0)}U2(this);return}zK(this,H,z,G,K)}),X("can_use_tool",(H)=>{KK(this,H)}),X("hook_callback",(H)=>{this.proc?.sendHookResponse(H.request_id,{})}),X("result",(H)=>{let z=this.persistResumableSessionId(),G=z?null:this.consumePendingConversationMaterialization(),W=[z,G].filter(Boolean).join(";")||null;if(this.accumulateResultStats(),this.openingTurnOwner)this.openingTurnOwner.sawResult=!0;if(this.userInterrupted){this.userInterrupted=!1,this.discardOrphanAssistant(),this.bgResumePending=!1;let O=this.proc?.lastResult.subtype??"unknown",A=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${O} isError=${A} — ignored`),this.status="idle";return}let K=H?.is_error!==!0?this.recordTurnAnchor(H?.checkpoint):null;if(H?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,j=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",q=typeof H?.error==="string"&&H.error.trim()?H.error.trim():L,D,F=!1,U=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),M=[W,K].filter(Boolean).join(";")||null;if(M)D=`⚠️ ${M}`,F=!0;else if(_)D=j?`⚠️ ${U} ${q},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)D=`⚠️ ${U} ${q}`,F=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=D,this.openingTurnOwner.terminalForcePush=F;if(M&&!this.currentTurn&&!this.openingTurn)g(this.chatId,`⚠️ ${M}`);if(B(`session "${this.sessionName}": SDK result subtype=${L} isError=${j} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${F}`),this.closeTurnCard(D,{forcePush:F,hasFreshResult:!0}).catch((O)=>{B(`session "${this.sessionName}": result card close failed: ${x(O)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((O)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${x(O)}`)})}),X("bg_task_started",(H)=>{let z=H.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,G=z?this.nativeAgentTools.get(z):void 0;if(G)G.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${H.task_id} type=${H.task_type??"-"} subagent=${H.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(H.description??"").slice(0,40)}`),this.applyBgStore(c9(this.bgStore(),{...H,tool_use_id:z})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(H)=>{this.applyBgStore(OJ(this.bgStore(),H)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(H)=>{this.applyBgStore(AJ(this.bgStore(),H)),this.onBackgroundTaskChanged(!!H.patch.status||H.patch.is_backgrounded===!0)}),X("bg_task_settled",(H)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${H.task_id} status=${H.status}`),this.applyBgStore(L6(this.bgStore(),H)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(H)=>{this.applyBgStore(TJ(this.bgStore(),H.thread_id,H.item_id,H.tool,H.phase,H.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:H,signal:z,expected:G})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${H} signal=${z} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),q=this.persistResumableSessionId(!1,$,!1),D=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${x(L)}`:null,q].filter(Boolean).join(";");if(D)g(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${D}`);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((L)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${x(L)}`)});let W=this.backendLabel($.provider),K=`code=${H??"null"}, signal=${z??"null"}`,_=G?`\uD83D\uDED1 ${W} 已退出`:`⚠️ ${W} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(_).catch((L)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${x(L)}`)});let j=this.waitForTurnCloses().catch((L)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${x(L)}`)});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 L=await Promise.allSettled([j,this.resetBackgroundTasks()]);for(let q of L)if(q.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${x(q.reason)}`);if(!G)await b(this.chatId,`⚠️ ${W} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((L)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${x(L)}`)})})}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=U5(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 M6(Z)}contextLimitForDisplay($=this.proc){return O6($?.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 z of Q)if(this.pendingTurnInputs.push(z.text),z.msgId){let G=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,G),this.pendingReactionIds.delete(z.msgId)}let Y=Q.map((z)=>z.wireText).join(`
282
+ `:"")+$,W=(K)=>{this.pendingReactionIds.set(K,""),(async()=>{let _=await Q$(K,"OneSecond");if(!_)return;if(this.pendingReactionIds.has(K))this.pendingReactionIds.set(K,_);else if(this.currentBatchReactionIds.has(K))this.currentBatchReactionIds.set(K,_);else g0(K,_)})().catch((_)=>{B(`session "${this.sessionName}": reaction tracking failed: ${x(_)}`)})};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,_=this.procEpoch,j=this.beginTurnOpen(K,_);try{this.pendingTurnInputs.push($);let L=await this.openTurnCard(j,J,"user_message");if(!L||this.currentTurn!==L)return;if(this.proc!==K||this.procEpoch!==_||!K.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(K.provider)} 已退出`);return}if(!await this.sendClaimedUserText(K,G))return;this.status="working"}finally{this.releaseTurnOpen(j)}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(H&&Q)W(Q)}hasPendingAsk(){return JK(this)}refreshPendingAsks(){Q7(this)}askBlockReason($){return C4(this,$)}onMultiMessageInbound($,Z,J,Q){return kW(this,$,Z,J,Q)}clearMultiMsgBuffer($){hQ(this,$)}onAskMessageAnswer($,Z,J){return QK(this,$,Z,J)}onAskAnswer($,Z,J,Q){return YK(this,$,Z,J,Q)}onAskCustomAnswer($,Z,J,Q){return nQ(this,$,Z,J,Q)}onPermissionDecision($,Z,J){return WK(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=A1(this.sessionName,"codex");if(H4(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=FY(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=A1(this.sessionName,"codex");if(!Y||Y.sessionId!==$)return null;try{H4(this.sessionName,"codex")}catch(X){let H=`已确认恢复点无 rollout,但作废失败: ${x(X)}`;return B(`session "${this.sessionName}": ${H} thread=${$}`),H}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let V=`已作废无 rollout 的恢复点 thread=${x0($)}`;return B(`session "${this.sessionName}": ${V} fullThread=${$}`),V}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Q=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Y=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Y){if(!Q)return null;let H=Error("Claude pending fork did not provide a materialized session id");if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}let V={provider:Z.provider,sessionId:Y,cwd:this.workDir};if(Q&&(Y===Q.launch.source.sessionId||Q.previousSessionId!==null&&Y===Q.previousSessionId)){let H=Error(`Claude fork did not materialize an independent session id (${Y})`);if(B(`session "${this.sessionName}": ${H.message}`),$)throw H;return H.message}try{O9(this.sessionName,V)}catch(H){let z=`会话恢复点持久化失败: ${x(H)}`,G=this.resumePersistenceError!==z;if(this.resumePersistenceError=z,Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;if(B(`session "${this.sessionName}": ${z}`),$)throw H;if(G&&J)g(this.chatId,`⚠️ ${z};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return z}if(Z.provider===this.selectedProvider)this.lastSessionRef=V,this.lastSessionId=Y;let X=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(X){let H=this.resumePersistenceError!==X;if(this.resumePersistenceError=X,$)throw Error(X);if(H&&J)g(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 N1(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(NJ(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 g(this.chatId,`⚠️ 运行任务面板更新失败:${Z}`)}async resetBackgroundTasks(){if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer);this.backgroundRefreshTimer=null;let $=Date.now();if(this.backgroundTasks=this.backgroundTasks.map((Z)=>_$(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=PY(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=(H,z)=>{$.on(H,(G)=>{if(!Q()){if(!Y)Y=!0,B(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(H)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(H!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!V)V=!0,B(`session "${this.sessionName}": ignore ${$.provider} event=${String(H)} while process stop is pending`);return}z(G)})};X("error",(H)=>{B(`session "${this.sessionName}": ${$.provider} process error: ${H}`)}),X("init",()=>{if($.provider==="codex"&&$.quotaWaitPromise){if(this.daemonRestoreRequired=!1,this.status==="starting")this.status=this.currentTurn?"working":"idle";this.opts.onLifecycleChange?.()}if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,B(`session "${this.sessionName}": SDK init#${this.initCount} pendingCount=${this.pendingUserMessageCount} midBuffer=${this.pendingMidTurnMsgs.length} currentTurn=${this.currentTurn?"yes":"no"} openingTurn=${this.openingTurn}`),this.currentTurn||this.openingTurn){if(this.pendingUserMessageCount>0)B(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let H=this.pendingUserMessageCount>0,z=!H&&this.bgResumePending;if(!H&&!z)return;let G=this.lastUserOpenId,W;try{W=this.beginTurnOpen($,J,!0)}catch(j){B(`session "${this.sessionName}": init turn-open ownership conflict: ${x(j)}`);return}if(this.bgResumePending=!1,H)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=H?[...this.currentBatchReactionIds.keys()]:[],_=()=>{for(let j of K){let L=this.currentBatchReactionIds.get(j);if(this.currentBatchReactionIds.delete(j),L)g0(j,L)}};(async()=>{try{let j=await this.openTurnCard(W,G,H?"user_message":"bg_task_resume");if(!Q()){if(B(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),j&&this.currentTurn===j)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);_();return}if(!j||this.currentTurn!==j){if(!this.ownsTurnOpen(W)){_();return}if(W.sawResult&&W.terminalSuffix)g(this.chatId,W.terminalSuffix);if(H)B(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),_();else if(this.bgResumeCardless=!0,W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else B(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(W.sawResult)W.sawResult=!1,B(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(W.terminalSuffix,{forcePush:W.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(W)}})().catch((j)=>{B(`session "${this.sessionName}": init turn-open handler failed: ${x(j)}`)})}),X("scheduled_turn_input",({text:H,promptId:z})=>{if($.provider!=="claude"&&$.provider!=="dsh")return;this.startScheduledTurnCard($,J,H,z)}),X("conversation_materialized",({session_id:H,source:z})=>{if($.provider!=="codex")return;if($.sessionId!==H){B(`session "${this.sessionName}": ignore mismatched Codex materialization session=${H} current=${$.sessionId??"MISS"} source=${z}`);return}B(`session "${this.sessionName}": Codex resume point materialized thread=${H} source=${z}`),this.persistResumableSessionId()}),X("conversation_materialization_failed",({session_id:H,source:z,error:G})=>{if($.provider!=="codex"||$.sessionId!==H)return;let W=`Codex 会话落盘确认失败,未写恢复点: ${x(G)}`,K=this.resumePersistenceError!==W;if(this.resumePersistenceError=W,B(`session "${this.sessionName}": ${W} thread=${H} source=${z}`),K)g(this.chatId,`⚠️ ${W}`)}),X("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),X("codex_account_changed",({accountId:H,diagnostics:z})=>{if(B(`session "${this.sessionName}": Codex account=${H}`),this.pendingAsks.clear(),this.pendingPermissions.clear(),z.length)B(`session "${this.sessionName}": Codex 未参与选号的账号: ${z.join(";")}`)}),X("turn_started",({retry:H})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)B(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),H){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let z=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!z){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=z?{...z}:null,this.currentTurnUsageBaselineKnown=!0}),X("token_usage",({totalUsage:H})=>{if(this.persistResumableSessionId(),H)this.usageTotalsSeedUnknown=!1}),X("turn_plan_updated",(H)=>{this.handleTurnPlanUpdated(H)}),X("plan_delta",(H)=>{this.handlePlanDelta(H)}),X("context_compacted",(H)=>{this.handleContextCompacted(H)}),X("rate_limits_updated",(H)=>{if($.provider==="codex"&&!E0($.tokenSourceId)?.codexApiProvider)UX(H,G$($))}),X("thread_goal_updated",(H)=>{this.handleThreadGoalUpdated(H)}),X("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),X("assistant_text",({text:H,parentToolUseId:z})=>{if(z)return;this.appendAssistant(H)}),X("assistant_block_stop",({parentToolUseId:H})=>{if(H)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),X("tool_use",({id:H,name:z,input:G,parentToolUseId:W})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(RJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}if(!W&&(z==="Task"||z==="Agent"||$.provider==="dsh"&&(z==="subagent"||z==="subagent_fork"))){let K=this.currentTurn;if(K)this.startWorkingFooter(K),this.finalizeCurrentAssistantSegment(),K.openBatchI=null,K.taskCreateI=null,K.taskUpdateI=null;if(this.onMainThreadAdvance(),this.nativeAgentTools.set(H,{confirmed:!1,input:G}),$.provider==="claude")this.lastMainTaskToolUseId=H,this.applyBgStore(c9(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:G?.description||G?.name||"子 Agent",prompt:G?.prompt,subagent_type:G?.subagent_type})),this.onBackgroundTaskChanged(!0);return}if(HK(this,H,z,G),!W)this.onMainThreadAdvance()}),X("tool_result",({tool_use_id:H,content:z,is_error:G,parentToolUseId:W,input:K})=>{if(W&&this.bgTaskOwns(W)){this.applyBgStore(xJ({active:this.backgroundTasks,pending:this.pendingBgTasks},W,H,z,G)),this.onBackgroundTaskChanged();return}let _=!W&&this.nativeAgentTools.get(H);if(_){if(this.nativeAgentTools.delete(H),this.lastMainTaskToolUseId===H)this.lastMainTaskToolUseId=null;if(G||$.provider==="claude"&&!_.confirmed&&_.input?.run_in_background!==!0){let j=typeof z==="string"?z:Array.isArray(z)?z.map((q)=>typeof q?.text==="string"?q.text:JSON.stringify(q)).join(`
283
+ `):JSON.stringify(z)??"MISS",L=this.backgroundTasks.find((q)=>q.toolUseId===H);if(!L)this.applyBgStore(c9(this.bgStore(),{task_id:H,tool_use_id:H,task_type:"subagent",description:_.input?.description||"子 Agent",prompt:_.input?.prompt})),L=this.backgroundTasks.find((q)=>q.toolUseId===H);this.applyBgStore(L6(this.bgStore(),{task_id:L.id,status:G?"failed":"completed",summary:j})),this.onBackgroundTaskChanged(!0)}M2(this);return}zK(this,H,z,G,K)}),X("can_use_tool",(H)=>{KK(this,H)}),X("hook_callback",(H)=>{this.proc?.sendHookResponse(H.request_id,{})}),X("result",(H)=>{let z=this.persistResumableSessionId(),G=z?null:this.consumePendingConversationMaterialization(),W=[z,G].filter(Boolean).join(";")||null;if(this.accumulateResultStats(),this.openingTurnOwner)this.openingTurnOwner.sawResult=!0;if(this.userInterrupted){this.userInterrupted=!1,this.discardOrphanAssistant(),this.bgResumePending=!1;let O=this.proc?.lastResult.subtype??"unknown",A=this.proc?.lastResult.is_error===!0;B(`session "${this.sessionName}": SDK result after user stop subtype=${O} isError=${A} — ignored`),this.status="idle";return}let K=H?.is_error!==!0?this.recordTurnAnchor(H?.checkpoint):null;if(H?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let _=this.pendingMidTurnMsgs.length>0,j=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",q=typeof H?.error==="string"&&H.error.trim()?H.error.trim():L,D,F=!1,M=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),U=[W,K].filter(Boolean).join(";")||null;if(U)D=`⚠️ ${U}`,F=!0;else if(_)D=j?`⚠️ ${M} ${q},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(j)D=`⚠️ ${M} ${q}`,F=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=D,this.openingTurnOwner.terminalForcePush=F;if(U&&!this.currentTurn&&!this.openingTurn)g(this.chatId,`⚠️ ${U}`);if(B(`session "${this.sessionName}": SDK result subtype=${L} isError=${j} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${F}`),this.closeTurnCard(D,{forcePush:F,hasFreshResult:!0}).catch((O)=>{B(`session "${this.sessionName}": result card close failed: ${x(O)}`)}),this.status="idle",_)this.drainMidTurnAndOpen().catch((O)=>{B(`session "${this.sessionName}": mid-turn drain failed: ${x(O)}`)})}),X("bg_task_started",(H)=>{let z=H.tool_use_id??($.provider==="claude"?this.lastMainTaskToolUseId:null)??void 0,G=z?this.nativeAgentTools.get(z):void 0;if(G)G.confirmed=!0;B(`session "${this.sessionName}": bg_task_started task=${H.task_id} type=${H.task_type??"-"} subagent=${H.subagent_type??"-"} toolUseId=${z?.slice(0,8)??"-"} desc=${(H.description??"").slice(0,40)}`),this.applyBgStore(c9(this.bgStore(),{...H,tool_use_id:z})),this.onBackgroundTaskChanged(!0)}),X("bg_task_progress",(H)=>{this.applyBgStore(OJ(this.bgStore(),H)),this.onBackgroundTaskChanged()}),X("bg_task_updated",(H)=>{this.applyBgStore(AJ(this.bgStore(),H)),this.onBackgroundTaskChanged(!!H.patch.status||H.patch.is_backgrounded===!0)}),X("bg_task_settled",(H)=>{if(B(`session "${this.sessionName}": bg_task_settled task=${H.task_id} status=${H.status}`),this.applyBgStore(L6(this.bgStore(),H)),this.onBackgroundTaskChanged(!0),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),X("subagent_step",(H)=>{this.applyBgStore(TJ(this.bgStore(),H.thread_id,H.item_id,H.tool,H.phase,H.brief)),this.onBackgroundTaskChanged()}),X("exit",({code:H,signal:z,expected:G})=>{if(B(`session "${this.sessionName}": ${$.provider} exited code=${H} signal=${z} expected=${G}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),q=this.persistResumableSessionId(!1,$,!1),D=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${x(L)}`:null,q].filter(Boolean).join(";");if(D)g(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${D}`);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((L)=>{B(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${x(L)}`)});let W=this.backendLabel($.provider),K=`code=${H??"null"}, signal=${z??"null"}`,_=G?`\uD83D\uDED1 ${W} 已退出`:`⚠️ ${W} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(_).catch((L)=>{B(`session "${this.sessionName}": process-exit current main-card close failed: ${x(L)}`)});let j=this.waitForTurnCloses().catch((L)=>{B(`session "${this.sessionName}": process-exit main-card close failed: ${x(L)}`)});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 L=await Promise.allSettled([j,this.resetBackgroundTasks()]);for(let q of L)if(q.status==="rejected")B(`session "${this.sessionName}": process-exit terminal cleanup failed: ${x(q.reason)}`);if(!G)await b(this.chatId,`⚠️ ${W} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((L)=>{B(`session "${this.sessionName}": process-exit cleanup rejected: ${x(L)}`)})})}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=M5(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 U6(Z)}contextLimitForDisplay($=this.proc){return O6($?.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 z of Q)if(this.pendingTurnInputs.push(z.text),z.msgId){let G=this.pendingReactionIds.get(z.msgId)??"";this.currentBatchReactionIds.set(z.msgId,G),this.pendingReactionIds.delete(z.msgId)}let Y=Q.map((z)=>z.wireText).join(`
284
284
 
285
285
  `),X=Q[Q.length-1]?.userOpenId??this.lastUserOpenId,H=await this.openTurnCard(J,X,"user_message");if(!H||this.currentTurn!==H){for(let z of Q){if(!z.msgId)continue;let G=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),G)g0(z.msgId,G)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let z of Q){if(!z.msgId)continue;let G=this.currentBatchReactionIds.get(z.msgId);if(this.currentBatchReactionIds.delete(z.msgId),G)g0(z.msgId,G)}this.status="stopped";return}try{if(!await this.sendClaimedUserText($,Y))return}catch(z){B(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${z}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await g(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${x(z)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Q=[],Y=(z)=>{Q.push(z)},V=J?await K0($,C.footer,this.footerElement(Z),{onFailure:Y}):!0;i0($);let X=await C0($,_2({suffix:Z}),Y);if(V&&X){await B$($);return}let H=`footer=${V?"ok":"MISS"}, settings=${X?"ok":"MISS"}`;B(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${H}`),await g(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${H})。
286
286
  ${v4(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(),H=this.withModel(Q.initialFooter??"Waiting...(0s)",X),z=T6({sessionName:this.sessionName,turn:Y,provider:X.provider,model:X.model??void 0,effort:X.effort??"MISS",kind:J,userInputs:V,initialFooter:H,directStart:Q.directStart}),G,W=await i(this.chatId,z,(q)=>{G=q});if(!W){if(!this.ownsTurnOpen($))return null;if(B(`session "${this.sessionName}": openTurnCard sendCard failed — surfacing via raw text`),J==="user_message")await g(this.chatId,`❌ 创建对话卡片失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。
@@ -289,18 +289,18 @@ ${k(q)}`);return null}let _=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(
289
289
  ${k({...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(!D4(J,Q)){let X=Q?.operation??"unknown operation",H=Q?.elementId?` element=${Q.elementId}`:"";B(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${X}${H} code=${J??"n/a"} — not rotating`),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),g(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(${Q.operation}, element=${Q.elementId??"MISS"});其余输出继续处理。
290
290
  ${k({...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,H)=>{if(!Y.value)Y.value={code:X,failure:H}};$.rotating=(async()=>{try{B(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${y9(Z)}`);let X=T6({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort??"MISS",kind:"card_full",userInputs:[]}),H,z=await i(this.chatId,X,(D)=>{H=D});if(!z){if(B(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await g(this.chatId,`⚠️ 续卡发送失败,后续内容到达时会再次尝试。
291
291
  ${k(H)}`);return}let G;try{G=await h$(z)}catch(D){if(B(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${D}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await g(this.chatId,`⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。
292
- ${k(D)}`);return}A$(G,2,(D,F)=>{if($.rotating){V(D,F);return}this.onCardWriteFailure($,G,D,F)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=G,$.cardRotationFailed=!1,$.messageId=z,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,_=$.currentAssistantText??"",j=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,K&&_){let D=C.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=D,$.currentAssistantText=_,$.segmentTexts.set(D,_)}if(_)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)N0($.cardId,P2(this.taskBoard),{type:"insert_before",targetElementId:C.footer});if($.planLiveInserted)N0($.cardId,i9($.planSteps,$.planExplanation,C.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?C.taskBoardLive:C.footer});for(let D of $.contextCompactionPending.values()){if(D.cardId!==Z)continue;D.cardId=G,D.created=!1,D.createFailure=void 0;let F=C.contextCompact(D.i);D.createPromise=U4(G,d9(D.i,D.notice,F),{type:"insert_before",targetElementId:k0($)}).then((U)=>{if(D.cardId===G)D.created=U.landed,D.createFailure=U.failure;return U.landed})}for(let[D,F]of j){if(K&&_&&D===K)continue;if(!F4(Z,D))continue;let U=$.assistantSegmentCount++,M=C.assistant(U);$.segmentTexts.set(M,F),await this.addCompletedAssistantSegment($,M,F)}sQ(this,Z,G,J,Q,$),await T1(Z),sQ(this,Z,G,J,Q,$);let L=new Set([C.taskBoardLive,C.planLive,...[...$.contextCompactionPending.values()].map((D)=>C.contextCompact(D.i))]);if(K)L.add(K);for(let D of J.values())if(D.output==null)L.add(C.tool(D.i));if(yz(Z).some((D)=>!L.has(D)))$.cardCapacityFailures.clear();await T1(G);try{await oQ($,Z);let D=$.mathRenderInflight?.get(Z);if(D?.size)await Promise.allSettled([...D]);await T1(Z);let F=$.mathRendered?.get(Z);for(let[y,S]of j){if(K&&_&&y===K)continue;if(F4(Z,y))continue;if(F?.has(y))continue;await P0(Z,y,this.completedAssistantElement(y,S))}let U=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",M=[],O=(y)=>{M.push(y)},A=await K0(Z,C.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${U}`)),{notifyCardFailure:!1,onFailure:O});i0(Z);let T=await C0(Z,_2({suffix:"\uD83D\uDCE8 转下一张"}),O);if(A&&T)await B$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${A} settings=${T}`),await g(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${A?"ok":"MISS"}, settings=${T?"ok":"MISS"}),本轮输出已续到新卡。
293
- ${v4(M)}`)}catch(D){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${D}`)}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++);N0(Z,cJ($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:k0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=C.goalUpdate(Z.goalUpdateCount++);N0(Z.cardId,lJ($,J),{type:"insert_before",targetElementId:k0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=C.goalUpdate($.goalUpdateCount++);N0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
292
+ ${k(D)}`);return}A$(G,2,(D,F)=>{if($.rotating){V(D,F);return}this.onCardWriteFailure($,G,D,F)});let W=$.assistantWriteInflight?.get(Z);if(W?.size)await Promise.allSettled([...W]);this.stopFooterStatus($),$.cardId=G,$.cardRotationFailed=!1,$.messageId=z,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let K=$.currentAssistantSegmentId,_=$.currentAssistantText??"",j=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,K&&_){let D=C.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=D,$.currentAssistantText=_,$.segmentTexts.set(D,_)}if(_)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)N0($.cardId,P2(this.taskBoard),{type:"insert_before",targetElementId:C.footer});if($.planLiveInserted)N0($.cardId,i9($.planSteps,$.planExplanation,C.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?C.taskBoardLive:C.footer});for(let D of $.contextCompactionPending.values()){if(D.cardId!==Z)continue;D.cardId=G,D.created=!1,D.createFailure=void 0;let F=C.contextCompact(D.i);D.createPromise=M4(G,d9(D.i,D.notice,F),{type:"insert_before",targetElementId:k0($)}).then((M)=>{if(D.cardId===G)D.created=M.landed,D.createFailure=M.failure;return M.landed})}for(let[D,F]of j){if(K&&_&&D===K)continue;if(!F4(Z,D))continue;let M=$.assistantSegmentCount++,U=C.assistant(M);$.segmentTexts.set(U,F),await this.addCompletedAssistantSegment($,U,F)}sQ(this,Z,G,J,Q,$),await T1(Z),sQ(this,Z,G,J,Q,$);let L=new Set([C.taskBoardLive,C.planLive,...[...$.contextCompactionPending.values()].map((D)=>C.contextCompact(D.i))]);if(K)L.add(K);for(let D of J.values())if(D.output==null)L.add(C.tool(D.i));if(yz(Z).some((D)=>!L.has(D)))$.cardCapacityFailures.clear();await T1(G);try{await oQ($,Z);let D=$.mathRenderInflight?.get(Z);if(D?.size)await Promise.allSettled([...D]);await T1(Z);let F=$.mathRendered?.get(Z);for(let[y,S]of j){if(K&&_&&y===K)continue;if(F4(Z,y))continue;if(F?.has(y))continue;await P0(Z,y,this.completedAssistantElement(y,S))}let M=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",U=[],O=(y)=>{U.push(y)},A=await K0(Z,C.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${M}`)),{notifyCardFailure:!1,onFailure:O});i0(Z);let T=await C0(Z,_2({suffix:"\uD83D\uDCE8 转下一张"}),O);if(A&&T)await B$(Z);else B(`session "${this.sessionName}": rotate old-card terminal MISS footer=${A} settings=${T}`),await g(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${A?"ok":"MISS"}, settings=${T?"ok":"MISS"}),本轮输出已续到新卡。
293
+ ${v4(U)}`)}catch(D){B(`session "${this.sessionName}": mid-turn rotate close-old failed: ${D}`)}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++);N0(Z,cJ($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:k0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=C.goalUpdate(Z.goalUpdateCount++);N0(Z.cardId,lJ($,J),{type:"insert_before",targetElementId:k0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=C.goalUpdate($.goalUpdateCount++);N0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
294
294
 
295
- 已清除`},{type:"insert_before",targetElementId:k0($)})}handleContextCompacted($){let Z=RB($);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<L7){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<L7||!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 H=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==H){this.rememberContextCompactionReceipt(Z,null,!0),B(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&X?.completionKey&&J.contextCompactionCompleting.has(X.completionKey)){B(`session "${this.sessionName}": context compaction alias already writing receipt=${V}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){B(`session "${this.sessionName}": identified context compaction duplicate ignored while anonymous completion writes`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.lastContextCompactionWasAnonymous&&Date.now()-J.lastContextCompactionCompletedAt<L7){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let U=tA($);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,H,!1);let M=J.contextCompactCount++,O=J.cardId,A=C.contextCompact(M),T={i:M,cardId:O,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};T.createPromise=U4(O,d9(M,$,A),{type:"insert_before",targetElementId:k0(J)}).then((y)=>{if(T.cardId===O)T.created=y.landed,T.createFailure=y.failure;return y.landed}),J.contextCompactionPending.set(U,T),B(`session "${this.sessionName}": context compaction start #${M+1} key=${U}`),M4(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<L7){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:rA(J),W=G?J.contextCompactionPending.get(G):void 0,K=G??z??"__anonymous__";if(J.contextCompactionCompleting.has(K)){B(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=eA(W?.notice,$),j=J.contextCompactionEndOnly.get(K),L=W?.i??j??J.contextCompactCount++;if(!W&&j===void 0)J.contextCompactionEndOnly.set(K,L);J.contextCompactionCompleting.add(K);let q=[...new Set([...RB(W?.notice??{}),...Z])];if(q.length>0)this.rememberContextCompactionReceipt(q,H,!1,K);let D=C.contextCompact(L),F=d9(L,_,D);B(`session "${this.sessionName}": context compaction completion write #${L+1} key=${K}`),(async()=>{let U=!1;if(!W)while(!0){let M=J.cardId;if(U=await X2(M,F,{type:"insert_before",targetElementId:k0(J)}),U)break;let O=J.rotating;if(O){await O;continue}if(J.cardId!==M)continue;break}else while(!0){let M=W.cardId;if(await W.createPromise,W.cardId!==M)continue;if(W.created)U=await K0(M,D,F);else{if(KJ(W.createFailure?.code,W.createFailure))vz(M,D),U=await K0(M,D,F,{notifyCardFailure:!1});if(!U)U=await X2(M,F,{type:"insert_before",targetElementId:k0(J)})}if(W.cardId!==M)continue;if(U){W.created=!0;break}let O=J.rotating;if(O){await O;continue}if(W.cardId!==M)continue;break}if(J.contextCompactionCompleting.delete(K),!U){B(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${K}`);return}if(G&&J.contextCompactionPending.get(G)===W)J.contextCompactionPending.delete(G);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",q.length>0){let M=[...this.contextCompactionReceipts.entries()].filter(([,O])=>O.completionKey===K).map(([O])=>O);this.rememberContextCompactionReceipt([...new Set([...q,...M])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${L+1} key=${K}`)})().catch((U)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${x(U)}`)}),M4(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>QN){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,H]of this.contextCompactionReceipts)if(H===V)this.contextCompactionReceipts.delete(X)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){B(`session "${this.sessionName}": turn/plan/updated with no current turn`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openBatchI=null,!Array.isArray($.plan))B(`session "${this.sessionName}": turn/plan/updated missing plan array`),Z.planSteps=[];else Z.planSteps=$.plan.map((J)=>({step:typeof J.step==="string"&&J.step?J.step:"MISS",status:typeof J.status==="string"&&J.status?J.status:"MISS"}));if(Z.planExplanation=typeof $.explanation==="string"?$.explanation:null,Z.planSteps.length>0)if(!Z.planLiveInserted){let J=Z.taskLiveInserted?C.taskBoardLive:C.footer;Z.planLiveInserted=!0,N0(Z.cardId,i9(Z.planSteps,Z.planExplanation,C.planLive),{type:"insert_before",targetElementId:J})}else K0(Z.cardId,C.planLive,i9(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&&R6(Z)===R6(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);M4(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
295
+ 已清除`},{type:"insert_before",targetElementId:k0($)})}handleContextCompacted($){let Z=RB($);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<L7){B(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Q=$.itemId?`item:${$.itemId}`:void 0,Y=Z.find((M)=>M.startsWith("turn:")),V=Q??Y,X=V?this.contextCompactionReceipts.get(V):void 0;if(Q&&!X&&$.phase!=="start"&&Y){let M=this.contextCompactionReceipts.get(Y);if(!M?.hasItemAlias&&M?.completed&&Date.now()-M.completedAt<L7||!M?.hasItemAlias&&M?.completionKey&&J?.contextCompactionCompleting.has(M.completionKey))V=Y,X=M,M.hasItemAlias=!0,this.contextCompactionReceipts.delete(Q),this.contextCompactionReceipts.set(Q,M)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),B(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");B(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(V&&X?.completed){B(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${V}`);return}let H=this.contextCompactionOwnerId(J);if(V&&X&&X.ownerId!==H){this.rememberContextCompactionReceipt(Z,null,!0),B(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${V} (turn owner changed)`);return}if(V&&X?.completionKey&&J.contextCompactionCompleting.has(X.completionKey)){B(`session "${this.sessionName}": context compaction alias already writing receipt=${V}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){B(`session "${this.sessionName}": identified context compaction duplicate ignored while anonymous completion writes`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.lastContextCompactionWasAnonymous&&Date.now()-J.lastContextCompactionCompletedAt<L7){B(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let M=tA($);if(J.contextCompactionPending.has(M)||J.contextCompactionCompleted.has(M)){B(`session "${this.sessionName}": duplicate context compaction start ignored key=${M}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,H,!1);let U=J.contextCompactCount++,O=J.cardId,A=C.contextCompact(U),T={i:U,cardId:O,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};T.createPromise=M4(O,d9(U,$,A),{type:"insert_before",targetElementId:k0(J)}).then((y)=>{if(T.cardId===O)T.created=y.landed,T.createFailure=y.failure;return y.landed}),J.contextCompactionPending.set(M,T),B(`session "${this.sessionName}": context compaction start #${U+1} key=${M}`),U4(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<L7){B(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let z=$.itemId||$.turnId;if(z&&J.contextCompactionCompleted.has(z)){B(`session "${this.sessionName}": duplicate context compaction completion ignored key=${z}`);return}let G=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:rA(J),W=G?J.contextCompactionPending.get(G):void 0,K=G??z??"__anonymous__";if(J.contextCompactionCompleting.has(K)){B(`session "${this.sessionName}": context compaction completion already writing key=${K}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let _=eA(W?.notice,$),j=J.contextCompactionEndOnly.get(K),L=W?.i??j??J.contextCompactCount++;if(!W&&j===void 0)J.contextCompactionEndOnly.set(K,L);J.contextCompactionCompleting.add(K);let q=[...new Set([...RB(W?.notice??{}),...Z])];if(q.length>0)this.rememberContextCompactionReceipt(q,H,!1,K);let D=C.contextCompact(L),F=d9(L,_,D);B(`session "${this.sessionName}": context compaction completion write #${L+1} key=${K}`),(async()=>{let M=!1;if(!W)while(!0){let U=J.cardId;if(M=await X2(U,F,{type:"insert_before",targetElementId:k0(J)}),M)break;let O=J.rotating;if(O){await O;continue}if(J.cardId!==U)continue;break}else while(!0){let U=W.cardId;if(await W.createPromise,W.cardId!==U)continue;if(W.created)M=await K0(U,D,F);else{if(KJ(W.createFailure?.code,W.createFailure))vz(U,D),M=await K0(U,D,F,{notifyCardFailure:!1});if(!M)M=await X2(U,F,{type:"insert_before",targetElementId:k0(J)})}if(W.cardId!==U)continue;if(M){W.created=!0;break}let O=J.rotating;if(O){await O;continue}if(W.cardId!==U)continue;break}if(J.contextCompactionCompleting.delete(K),!M){B(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${K}`);return}if(G&&J.contextCompactionPending.get(G)===W)J.contextCompactionPending.delete(G);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",q.length>0){let U=[...this.contextCompactionReceipts.entries()].filter(([,O])=>O.completionKey===K).map(([O])=>O);this.rememberContextCompactionReceipt([...new Set([...q,...U])],null,!0)}B(`session "${this.sessionName}": context compaction completed #${L+1} key=${K}`)})().catch((M)=>{J.contextCompactionCompleting.delete(K),B(`session "${this.sessionName}": context compaction completion transaction failed: ${x(M)}`)}),U4(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>QN){let V;for(let X of this.contextCompactionReceipts.values()){if(X.completed){V=X;break}V??=X}if(!V)break;for(let[X,H]of this.contextCompactionReceipts)if(H===V)this.contextCompactionReceipts.delete(X)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){B(`session "${this.sessionName}": turn/plan/updated with no current turn`);return}if(this.startWorkingFooter(Z),Z.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(Z.openBatchI=null,!Array.isArray($.plan))B(`session "${this.sessionName}": turn/plan/updated missing plan array`),Z.planSteps=[];else Z.planSteps=$.plan.map((J)=>({step:typeof J.step==="string"&&J.step?J.step:"MISS",status:typeof J.status==="string"&&J.status?J.status:"MISS"}));if(Z.planExplanation=typeof $.explanation==="string"?$.explanation:null,Z.planSteps.length>0)if(!Z.planLiveInserted){let J=Z.taskLiveInserted?C.taskBoardLive:C.footer;Z.planLiveInserted=!0,N0(Z.cardId,i9(Z.planSteps,Z.planExplanation,C.planLive),{type:"insert_before",targetElementId:J})}else K0(Z.cardId,C.planLive,i9(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&&R6(Z)===R6(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);U4(Z.cardId,Y)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
296
296
 
297
297
  `).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 后台轮输出(未能建卡,纯文本兜底):
298
298
 
299
299
  ${J}`)}completedAssistantElement($,Z){if(pQ(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 dW(Q);if(!await K0(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=k0($),V=(async()=>{if(!await X2(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(pQ(J)){let H=this.replaceSegmentWithMathImgs($,Q,Z,J).catch((z)=>B(`session "${this.sessionName}": math render ${Z} failed: ${z}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Q)??$.mathRenderInflight.set(Q,new Set),$.mathRenderInflight.get(Q).add(H),H.finally(()=>$.mathRenderInflight?.get(Q)?.delete(H))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Q)??$.assistantWriteInflight.set(Q,new Set),$.assistantWriteInflight.get(Q).add(V),V.finally(()=>$.assistantWriteInflight?.get(Q)?.delete(V)),V}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Q=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
300
300
 
301
301
  ${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 xW($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return $0($)}sendOutboundPath($,Z){let J=e6($.trim());if(!J)return;let Q=this.currentTurn;if(Q?.outboundSeenPaths.has(J))return;if(Q?.outboundSeenPaths.add(J),!sA(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),R9(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 aK({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}=N4(Date.now()-$.footerStatusStartedAt,P7()),H=Z===TB?this.proc?.lastThinkingTokens:null,z=typeof H==="number"?` · 约 ${H} tokens`:"";$.footerStatusWriteCardId=V,this.replaceFooterContent(V,this.withModel(`${Z}${z} (${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}=N4(Date.now()-$.footerStatusStartedAt,P7());$.footerStatusHandle=setTimeout(()=>{Q(),Y()},Math.max(1,Math.ceil(V)))};Q(),Y()}startThinkingFooter($){this.startFooterStatus($,TB)}startWritingFooter($){this.startFooterStatus($,$N)}startWorkingFooter($){this.startFooterStatus($,ZN)}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 H=X.windows.find((G)=>G.kind==="fiveHour");if(Q.kind==="claude-subscription"){let G=Qz(X,V),W={percent:null,resetsAt:null};return this.fmtDualWindowSuffix(H??W,G??W)}let z=X.windows.find((G)=>G.kind==="weekly");if(H||z)return this.fmtDualWindowSuffix(H??null,z??null)}return` | ${HQ(X)}`}if($==="codex"){let X=Y??(Z?.provider==="codex"?b5(G$(Z)):null);if(!X)return" | 额度 MISS";let H=X.read();if(!H)return" | 额度 MISS";return this.fmtDualWindowSuffix(H.fiveHour,H.weekly)}return" | 额度 MISS"}fmtDualWindowSuffix($,Z){let J=(V)=>{if(!V)return null;if(V.percent==null)return"MISS";let X=V.resetsAt&&V.resetsAt.getTime()>Date.now()?I$(V.resetsAt):"",H=`${Math.round(V.percent)}%`;return X?`${X}·${H}`:H},Q=J($),Y=J(Z);if(Q&&Y)return` | ${Q}·[${Y}]`;if(Q)return` | ${Q}`;if(Y)return` | [${Y}]`;return" | 额度 MISS"}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Q)=>Q.status==="rejected").map((Q)=>Q.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(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,G$(Q)):this.currentTokenSource(),codexUsage:Q?.provider==="codex"&&!E0(Q.tokenSourceId)?.codexApiProvider?b5(G$(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 oQ(Q),Q.fileDelivery)try{for(let A of await Q.fileDelivery.finish())Q.outboundSentPaths.add(A)}catch(A){B(`session "${this.sessionName}": file delivery close failed: ${x(A)}`),await g(this.chatId,`❌ 文件交付收尾失败:${x(A)}`)}finally{this.fileDeliveries.delete(Q.fileDelivery)}this.stopFooterStatus(Q);let Y=(Date.now()-Q.startedAt)/1000,V=Q.cardId,X=Q.segmentTexts;await T1(V);let H=new Map;if(Q.currentAssistantSegmentId&&Q.currentAssistantText.trim()){let{currentAssistantSegmentId:A,currentAssistantText:T}=Q;if(!await this.addCompletedAssistantSegment(Q,A,T))H.set(A,T);Q.currentAssistantSegmentId=null,Q.currentAssistantText=""}let z=Q.assistantWriteInflight?.get(V);if(z?.size)await Promise.allSettled([...z]);let G=Q.mathRenderInflight?.get(V);if(G?.size)await Promise.allSettled([...G]);let W=Q.mathRendered?.get(V);for(let[A,T]of X){if(F4(V,A)){H.set(A,T);continue}if(W?.has(A))continue;await P0(V,A,this.completedAssistantElement(A,T))}if(Q.cardRotationFailed)for(let[A,T]of X)H.set(A,T);let K=Z?Z:"✅",_=[`${K} ⏱ ${R0(Y)}`];if(J.hasFreshResult){let{contextTokens:A,contextLimit:T}=$,y=Q.provider==="claude",S=mJ(A,T,y?0:void 0);if(S)_.push(`\uD83E\uDDE0 ${S}`);let h=$.lastTurnDelta?.costUsd??0;if(h>0)_.push(`\uD83D\uDCB0 $${h.toFixed(3)}`)}if(Q.contextCompactCount>0)_.push(`\uD83D\uDEA8 压缩×${Q.contextCompactCount}`);if(Q.outboundSentPaths.size>0)_.push(`\uD83D\uDCCE ${Q.outboundSentPaths.size}`);let j=this.modelLine(Q);if(j)_.push(j);let L=_.join(" | "),q=J.hasFreshResult?pJ($.lastTurnUsage)+(Q.cardRotationFailed?"":await this.footerUsageSuffix(Q.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage,Q.model)):"",D=q?`${L}
302
- ${q}`:L,F=[],U=(A)=>{F.push(A)},M=await K0(V,C.footer,this.footerElement(D),{onFailure:U});i0(V);let O=await C0(V,_2({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}),U);if(M&&O)await B$(V);else{let A=`footer=${M?"ok":"MISS"}, settings=${O?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${A}`),await g(this.chatId,`⚠️ 对话卡片终态写入失败 (${A})。本轮已结束: ${K}
303
- ${v4(F)}`)}for(let A of H.values())await this.sendAssistantTextFallback(A,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.cardRotationFailed)e1(Q.messageId,[Q.userOpenId])}}});function P$($){return{card:{type:"raw",data:$}}}import{randomUUID as VN}from"node:crypto";function UY($){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(G$($.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:u0().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 SB($,Z,J,Q,Y){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let V=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(V.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof V.message_id!=="string"||!V.message_id.startsWith("om_"))throw Error("message_id required");if(!Y||V.message_id!==Y)throw Error("stale or mismatched model panel");if(!J||J.message_id!==V.message_id||J.chat_id!==Z.chat_id||J.msg_type!=="interactive"||J.sender?.sender_type!=="app"||J.sender.id!==Q)throw Error("model card must belong to this app and debug chat");if(!V.value||typeof V.value!=="object"||Array.isArray(V.value))throw Error("action value required");let X={};for(let[H,z]of Object.entries(V.value)){if(!HN.has(H))throw Error(`unsupported model action field: ${H}`);if(H==="page"){if(typeof z!=="number"||!Number.isSafeInteger(z)||z<0)throw Error("invalid page");X.page=z}else{if(typeof z!=="string"||!z.trim()||z.length>1024)throw Error(`invalid ${H}`);X[H]=z.trim()}}if(!XN.has(String(X.kind)))throw Error("only model panel actions are supported");for(let H of["panel_id","source_id"])if(!X[H])throw Error(`${H} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(X.kind))&&!X.model)throw Error("model required");if(X.kind==="model_effort_select"&&!X.effort)throw Error("effort required");if(X.kind==="model_page"&&X.page===void 0)throw Error("page required");if(X.kind==="model_list_open"&&X.mode!=="select"&&X.mode!=="add")throw Error("invalid model list mode");if(X.provider!==void 0&&!C$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${VN()}`,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 XN,HN;var CB=R(()=>{B0();Q0();D0();XN=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"]),HN=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as zN}from"node:http";import{randomUUID as GN}from"node:crypto";function wB($){if($.allowReply&&$.buttons?.length)throw Error(kB);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Q=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Y=new Date,V=`${String(Y.getHours()).padStart(2,"0")}:${String(Y.getMinutes()).padStart(2,"0")}`,X=[];for(let z of $.images??[])if(z.key)X.push({tag:"img",img_key:z.key,alt:{tag:"plain_text",content:"screenshot"}});else{let G=z.error?`
302
+ ${q}`:L,F=[],M=(A)=>{F.push(A)},U=await K0(V,C.footer,this.footerElement(D),{onFailure:M});i0(V);let O=await C0(V,_2({durationSec:Y,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}),M);if(U&&O)await B$(V);else{let A=`footer=${U?"ok":"MISS"}, settings=${O?"ok":"MISS"}`;B(`session "${this.sessionName}": terminal card transaction incomplete card=${V.slice(0,12)} ${A}`),await g(this.chatId,`⚠️ 对话卡片终态写入失败 (${A})。本轮已结束: ${K}
303
+ ${v4(F)}`)}for(let A of H.values())await this.sendAssistantTextFallback(A,"CardKit 元素未落地");if((J.forcePush||!Z)&&Q.userOpenId&&Q.messageId&&!Q.cardRotationFailed)e1(Q.messageId,[Q.userOpenId])}}});function P$($){return{card:{type:"raw",data:$}}}import{randomUUID as VN}from"node:crypto";function MY($){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(G$($.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:u0().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 SB($,Z,J,Q,Y){if(!$||typeof $!=="object"||Array.isArray($))throw Error("bad action body");let V=$;if(!Z.chat_id.startsWith("oc_")||!Z.sender_open_id.startsWith("ou_"))throw Error("invalid debug context");if(V.chat_id!==Z.chat_id)throw Error("debug chat mismatch");if(typeof V.message_id!=="string"||!V.message_id.startsWith("om_"))throw Error("message_id required");if(!Y||V.message_id!==Y)throw Error("stale or mismatched model panel");if(!J||J.message_id!==V.message_id||J.chat_id!==Z.chat_id||J.msg_type!=="interactive"||J.sender?.sender_type!=="app"||J.sender.id!==Q)throw Error("model card must belong to this app and debug chat");if(!V.value||typeof V.value!=="object"||Array.isArray(V.value))throw Error("action value required");let X={};for(let[H,z]of Object.entries(V.value)){if(!HN.has(H))throw Error(`unsupported model action field: ${H}`);if(H==="page"){if(typeof z!=="number"||!Number.isSafeInteger(z)||z<0)throw Error("invalid page");X.page=z}else{if(typeof z!=="string"||!z.trim()||z.length>1024)throw Error(`invalid ${H}`);X[H]=z.trim()}}if(!XN.has(String(X.kind)))throw Error("only model panel actions are supported");for(let H of["panel_id","source_id"])if(!X[H])throw Error(`${H} required`);if(["model_select","model_effort_select","model_add","model_remove","model_custom_remove"].includes(String(X.kind))&&!X.model)throw Error("model required");if(X.kind==="model_effort_select"&&!X.effort)throw Error("effort required");if(X.kind==="model_page"&&X.page===void 0)throw Error("page required");if(X.kind==="model_list_open"&&X.mode!=="select"&&X.mode!=="add")throw Error("invalid model list mode");if(X.provider!==void 0&&!C$(X.provider))throw Error("invalid provider");return{event_id:`debug-model-${VN()}`,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 XN,HN;var CB=R(()=>{B0();Q0();D0();XN=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"]),HN=new Set(["kind","panel_id","source_id","model","effort","provider","page","mode"])});import{createServer as zN}from"node:http";import{randomUUID as GN}from"node:crypto";function wB($){if($.allowReply&&$.buttons?.length)throw Error(kB);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Q=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Y=new Date,V=`${String(Y.getHours()).padStart(2,"0")}:${String(Y.getMinutes()).padStart(2,"0")}`,X=[];for(let z of $.images??[])if(z.key)X.push({tag:"img",img_key:z.key,alt:{tag:"plain_text",content:"screenshot"}});else{let G=z.error?`
304
304
  ${$0(z.error)}`:"";X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${z.src}${G}</font>`})}if(X.push({tag:"markdown",content:HZ($.text??"")||"_(空消息)_"}),$.resolution){let z=$.resolution,G=z.kind==="text"?"已回复":`已选择:${z.text}`,W;if(z.status==="processing")W=`<font color='blue'>⏳ ${G} · 推送中…</font>`;else if(z.status==="failed")W=`<font color='red'>⚠️ ${z.kind==="text"?G:`已选:${z.text}`} · 回调失败:${$0(z.detail??"未知")} · ${V}</font>`;else if(z.status==="delivered")W=`<font color='green'>✅ ${G} · 反馈已送达 · ${V}</font>`;else if(z.status==="unknown")W=`<font color='red'>⚠️ ${G} · 送达状态未知,禁止自动重试 · ${V}</font>`;else W=`<font color='green'>✅ ${G} · ${V}</font>`;if(X.push({tag:"markdown",content:W}),z.status==="delivered"&&z.reply)X.push({tag:"markdown",content:$0(z.reply)})}let H=Q&&(!$.resolution||$.resolution.status==="failed");if(H&&$.buttons?.length)X.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((z)=>({tag:"button",text:{tag:"plain_text",content:z.text},type:z.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:z.id}}]}))}]});if(X.push({tag:"hr"}),X.push({tag:"markdown",content:`<font color='grey'>via notify · ${V}</font>`}),H&&$.allowReply)X.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"回复"},type:"primary",behaviors:[{type:"callback",value:{kind:"notify_reply",notify_id:$.notifyId}}]}]}]});return{schema:"2.0",config:Q?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:X}}}function v1($,Z,J){let Q=J?.status??Z.status,Y={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},V=[{tag:"markdown",content:`通知:${$0($.title)}`}];if(Z.response)V.push({tag:"markdown",content:$0(Z.response.text)});if(Q==="waiting")V.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
305
305
  你的下一条文字优先用于这条通知,完成后再回答 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'>${$0(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:$0(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 _N($){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(!BN.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>bB)return{error:`button "${Y}" text > ${bB} chars`};if(Z.has(Y))return{error:`button id "${Y}" duplicated`};Z.add(Y);let X=String(Q.type??"default").toLowerCase(),H=KN.has(X)?X:"default";J.push({id:Y,text:V,type:H})}return{buttons:J}}function jN($){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 yB($){try{let Z=zN((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 qN(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?k(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 qN($,Z,J=J0){let Q=new URL($.url??"/","http://localhost"),Y=(N,f)=>{Z.statusCode=N,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(f)},V=(N,f)=>{Z.statusCode=N,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(f))};if($.method==="GET"&&Q.pathname==="/")return Y(200,`lodestar notify
306
306
  `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?} → push card to group
@@ -309,8 +309,8 @@ ${$0(z.error)}`:"";X.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF
309
309
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
310
310
  card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
311
311
  `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) — omit to poll
312
- `);if($.method==="GET"&&Q.pathname.startsWith("/notify/result/")){let N;try{N=decodeURIComponent(Q.pathname.slice(15)).trim()}catch{return Y(400,"invalid notify_id encoding")}if(!N)return Y(400,"missing notify_id in path");let f=Y1(N);if(!f)return V(404,{error:"unknown notify_id",notify_id:N});return V(200,ZK(f))}if($.method!=="POST"||Q.pathname!=="/notify")return Y(405,"use POST /notify");let X="",H=0;$.setEncoding("utf8");for await(let N of $)if(H+=Buffer.byteLength(N),H<=MY)X+=N;else X="";if(H>MY)return Y(413,`request body exceeds ${MY} bytes`);let z={};try{z=JSON.parse(X)}catch{return Y(400,"bad json")}if(!z||typeof z!=="object"||Array.isArray(z))return Y(400,"body must be an object");if(z.allow_reply!==void 0&&typeof z.allow_reply!=="boolean")return Y(400,'"allow_reply" must be a boolean');let G=z.allow_reply===!0,W=String(z.project??"").trim(),K=String(z.text??""),_=String(z.title??"").trim(),j=String(z.level??"info").toLowerCase();if(!W)return Y(400,'missing "project"');if(!K)return Y(400,'missing "text"');let{buttons:L,error:q}=_N(z.buttons);if(q)return Y(400,q);let{url:D,error:F}=jN(z.callback);if(F)return Y(400,F);let U=!!(L&&L.length);if(U&&G)return Y(400,kB);let M=U||G,O=D??"",A=WN.has(j)?j:"info",T=_||W,y=J.sanitizeSessionName(W),S=J.chatIdForSession(y);if(!S)return B(`notify: project "${W}" (sanitized "${y}") 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 h=Array.isArray(z.images)?z.images:[],l=[];for(let N of h){let f=String(N??"").trim();if(!f)continue;let z0,n=await J.uploadImageKey(f,(T0)=>{z0=T0});l.push({key:n??"",src:f,...z0===void 0?{}:{error:k(z0)}})}let E=M?`nf_${GN()}`:"",m=wB({title:T,text:K,level:A,images:l,buttons:L,allowReply:G,notifyId:E}),Y0,w=await J.sendCard(S,m,(N)=>{Y0=N});if(!w)return B(`notify: sendCard failed → 502 (project="${W}" chat=${S.slice(0,8)}…)`),Y(502,`feishu sendCard failed: ${k(Y0)}`);if(M&&E){let N={notifyId:E,callbackUrl:O,chatId:S,messageId:w,project:W,title:T,text:K,level:A,imageKeys:l,buttons:L,allowReply:G,createdAt:Date.now()};tW(N)}B(`notify: → ${W} (${S.slice(0,8)}…) level=${A} bytes=${K.length} images=${l.length} buttons=${L?.length??0} allowReply=${G} push=${M&&!!O?1:0} msg=${w}`),V(200,{ok:!0,chat_id:S,message_id:w,...E?{notify_id:E}:{}})}function f1($,Z){return wB({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var WN,KN,BN,bB=64,kB='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply',MY=4194304;var D7=R(()=>{I();e();b2();h0();q3();WN=new Set(["info","warn","error"]),KN=new Set(["default","primary","danger"]),BN=/^[A-Za-z0-9_-]{1,64}$/});var hB=IY((kh,fB)=>{var{readFileSync:LN,rmSync:PN}=R2("node:fs"),{homedir:vB}=R2("node:os"),{join:U3}=R2("node:path"),{managedClaudePluginDir:DN}=b7();function FN($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Q=Z??[U3(vB(),".codex","skills"),U3(vB(),".claude","skills"),U3(DN(),"skills")],Y=[];for(let V of Q){let X=U3(V,$),H=U3(X,"SKILL.md"),z;try{z=LN(H,"utf8")}catch(K){if(K.code==="ENOENT")continue;let _=Error(`skill: obsolete removal failed (${H}): ${K}`,{cause:K});J(_.message),Y.push(_);continue}let G=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(z)?.[1],W=/^name:[ \t]*(?:"([^"]*)"|'([^']*)'|([^\s#]+))[ \t]*$/m.exec(G??"");if(!W||(W[1]??W[2]??W[3])!==$){J(`skill: obsolete path preserved because ownership is unclear ${H}`);continue}try{PN(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let _=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(_.message),Y.push(_)}}if(Y.length)throw AggregateError(Y,`Failed to remove obsolete Skill ${$}`)}fB.exports={removeManagedSkill:FN}});import{existsSync as gB,readFileSync as mB}from"node:fs";import{homedir as IB}from"node:os";import{join as M3}from"node:path";function F7($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[M3(IB(),".codex","skills"),M3(IB(),".claude","skills")];for(let Q of J){let Y=M3(Q,$.name,"SKILL.md");try{let V=gB(Y)?mB(Y,"utf8"):null;if(V===$.body)continue;s0(Y,$.body),B(`skill: ${V===null?"installed":"updated"} ${Y}`)}catch(V){B(`skill: sync failed (${Y}): ${V}`)}}if(!Z)UN($,x2)}function UN($,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)+`
313
- `;for(let[V,X]of[[J,Y],[Q,$.body]])try{let H=gB(V)?mB(V,"utf8"):null;if(H===X)continue;s0(V,X),B(`skill: ${H===null?"installed":"updated"} ${V}`)}catch(H){B(`skill: Claude plugin sync failed (${V}): ${H}`)}}function U7($,Z){pB.removeManagedSkill($,Z,B)}var pB;var M7=R(()=>{I();v0();V0();pB=hY(hB(),1)});function MN($){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`---
312
+ `);if($.method==="GET"&&Q.pathname.startsWith("/notify/result/")){let N;try{N=decodeURIComponent(Q.pathname.slice(15)).trim()}catch{return Y(400,"invalid notify_id encoding")}if(!N)return Y(400,"missing notify_id in path");let f=Y1(N);if(!f)return V(404,{error:"unknown notify_id",notify_id:N});return V(200,ZK(f))}if($.method!=="POST"||Q.pathname!=="/notify")return Y(405,"use POST /notify");let X="",H=0;$.setEncoding("utf8");for await(let N of $)if(H+=Buffer.byteLength(N),H<=UY)X+=N;else X="";if(H>UY)return Y(413,`request body exceeds ${UY} bytes`);let z={};try{z=JSON.parse(X)}catch{return Y(400,"bad json")}if(!z||typeof z!=="object"||Array.isArray(z))return Y(400,"body must be an object");if(z.allow_reply!==void 0&&typeof z.allow_reply!=="boolean")return Y(400,'"allow_reply" must be a boolean');let G=z.allow_reply===!0,W=String(z.project??"").trim(),K=String(z.text??""),_=String(z.title??"").trim(),j=String(z.level??"info").toLowerCase();if(!W)return Y(400,'missing "project"');if(!K)return Y(400,'missing "text"');let{buttons:L,error:q}=_N(z.buttons);if(q)return Y(400,q);let{url:D,error:F}=jN(z.callback);if(F)return Y(400,F);let M=!!(L&&L.length);if(M&&G)return Y(400,kB);let U=M||G,O=D??"",A=WN.has(j)?j:"info",T=_||W,y=J.sanitizeSessionName(W),S=J.chatIdForSession(y);if(!S)return B(`notify: project "${W}" (sanitized "${y}") 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 h=Array.isArray(z.images)?z.images:[],l=[];for(let N of h){let f=String(N??"").trim();if(!f)continue;let z0,n=await J.uploadImageKey(f,(T0)=>{z0=T0});l.push({key:n??"",src:f,...z0===void 0?{}:{error:k(z0)}})}let E=U?`nf_${GN()}`:"",m=wB({title:T,text:K,level:A,images:l,buttons:L,allowReply:G,notifyId:E}),Y0,w=await J.sendCard(S,m,(N)=>{Y0=N});if(!w)return B(`notify: sendCard failed → 502 (project="${W}" chat=${S.slice(0,8)}…)`),Y(502,`feishu sendCard failed: ${k(Y0)}`);if(U&&E){let N={notifyId:E,callbackUrl:O,chatId:S,messageId:w,project:W,title:T,text:K,level:A,imageKeys:l,buttons:L,allowReply:G,createdAt:Date.now()};tW(N)}B(`notify: → ${W} (${S.slice(0,8)}…) level=${A} bytes=${K.length} images=${l.length} buttons=${L?.length??0} allowReply=${G} push=${U&&!!O?1:0} msg=${w}`),V(200,{ok:!0,chat_id:S,message_id:w,...E?{notify_id:E}:{}})}function f1($,Z){return wB({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var WN,KN,BN,bB=64,kB='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply',UY=4194304;var D7=R(()=>{I();e();b2();h0();q3();WN=new Set(["info","warn","error"]),KN=new Set(["default","primary","danger"]),BN=/^[A-Za-z0-9_-]{1,64}$/});var hB=IY((kh,fB)=>{var{readFileSync:LN,rmSync:PN}=R2("node:fs"),{homedir:vB}=R2("node:os"),{join:M3}=R2("node:path"),{managedClaudePluginDir:DN}=b7();function FN($,Z,J=console.log){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){J(`skill: sync disabled, skip removal ${$}`);return}let Q=Z??[M3(vB(),".codex","skills"),M3(vB(),".claude","skills"),M3(DN(),"skills")],Y=[];for(let V of Q){let X=M3(V,$),H=M3(X,"SKILL.md"),z;try{z=LN(H,"utf8")}catch(K){if(K.code==="ENOENT")continue;let _=Error(`skill: obsolete removal failed (${H}): ${K}`,{cause:K});J(_.message),Y.push(_);continue}let G=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(z)?.[1],W=/^name:[ \t]*(?:"([^"]*)"|'([^']*)'|([^\s#]+))[ \t]*$/m.exec(G??"");if(!W||(W[1]??W[2]??W[3])!==$){J(`skill: obsolete path preserved because ownership is unclear ${H}`);continue}try{PN(X,{recursive:!0,force:!1}),J(`skill: removed obsolete ${X}`)}catch(K){let _=Error(`skill: obsolete removal failed (${X}): ${K}`,{cause:K});J(_.message),Y.push(_)}}if(Y.length)throw AggregateError(Y,`Failed to remove obsolete Skill ${$}`)}fB.exports={removeManagedSkill:FN}});import{existsSync as gB,readFileSync as mB}from"node:fs";import{homedir as IB}from"node:os";import{join as U3}from"node:path";function F7($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[U3(IB(),".codex","skills"),U3(IB(),".claude","skills")];for(let Q of J){let Y=U3(Q,$.name,"SKILL.md");try{let V=gB(Y)?mB(Y,"utf8"):null;if(V===$.body)continue;s0(Y,$.body),B(`skill: ${V===null?"installed":"updated"} ${Y}`)}catch(V){B(`skill: sync failed (${Y}): ${V}`)}}if(!Z)MN($,x2)}function MN($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){B(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=U3(Z,".claude-plugin","plugin.json"),Q=U3(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)+`
313
+ `;for(let[V,X]of[[J,Y],[Q,$.body]])try{let H=gB(V)?mB(V,"utf8"):null;if(H===X)continue;s0(V,X),B(`skill: ${H===null?"installed":"updated"} ${V}`)}catch(H){B(`skill: Claude plugin sync failed (${V}): ${H}`)}}function M7($,Z){pB.removeManagedSkill($,Z,B)}var pB;var U7=R(()=>{I();v0();V0();pB=hY(hB(),1)});function UN($){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`---
314
314
  name: ${cB}
315
315
  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.")}
316
316
  ---
@@ -570,19 +570,19 @@ is the script's acknowledgement, distinct from the user's response.
570
570
  Hand-edits will be overwritten — set
571
571
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
572
572
  to maintain the file yourself.
573
- `}function lB(){F7({name:cB,body:MN(p.notify.port)})}var cB="feishu-notify";var uB=R(()=>{f0();M7()});import{randomUUID as ON}from"node:crypto";function dB($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,H)=>{if(!V)return"通知已过期或已移除";if(!H)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(E4(V.notifyId))return"通知正在处理中";return null},Q=async(V,X)=>{$.log(`notify-reply: ${X}`);let H;if(!await $.sendText(V,`❌ ${X}`,(z)=>{H=z}))throw Error(`通知回复错误提示发送失败: ${k(H)};原错误:${X}`)},Y=async(V,X,H,z)=>{try{await $.updateCard(X,H)}catch(G){await Q(V.chatId,`${z},卡片更新失败:${k(G)}`)}};return{async recover(V){if(V.dispatchState&&V.unknownAt){let z=V.dispatchState,G=V.buttons.find((W)=>W.id===z.buttonId);await Y(V,V.messageId,f1(V,{status:"unknown",buttonId:z.buttonId,text:G?.text??z.buttonId,operatorOpenId:z.openId,detail:V.unknownReason}),"按钮回调送达状态未知");return}let X=V.replyState;if(!X||!V.unknownAt)return;let H={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Y(V,X.promptMessageId,v1(V,X,H),"回复送达状态未知"),await Y(V,V.messageId,f1(V,H),"回复送达状态未知")},async open(V,X,H){let z=Y1(V),G=J(z,X,H);if(G||!z)return{ok:!1,message:G};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let W=lQ(z.chatId);if(W.some((K)=>K.replyState?.status==="sending"||E4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};K3(V);try{for(let L of W){let q={...L.replyState,status:"cancelled",cancelReason:"switched"};S4(L.notifyId,q),await Y(L,q.promptMessageId,v1(L,q),"已放弃上一条回复并切换通知")}let K={id:ON(),openId:H,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_,j=await $.sendCard(z.chatId,v1(z,K),(L)=>{_=L});if(!j)return{ok:!1,message:`等待输入卡片发送失败,未开始接收回复,请重新点击「回复」
574
- ${k(_)}`};K.promptMessageId=j;try{S4(V,K)}catch(L){let q=`等待输入状态保存失败,未开始接收回复:${Z(L)}`;return await Y(z,j,v1(z,K,{status:"failed",detail:q}),q),{ok:!1,message:q,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{B3(V),$.onWaitingChanged(z.chatId)}},async cancel(V,X,H,z){let G=Y1(V),W=J(G,H,z);if(W||!G)return{ok:!1,message:W};let K=G.replyState;if(!K||K.id!==X||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...K,status:"cancelled"};return S4(V,_),$.onWaitingChanged(G.chatId),await Y(G,K.promptMessageId,v1(G,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:H,messageId:z,text:G,createTime:W}=V;if(!H||!z||!G.trim())return!1;if($K(X,z))return!0;let K=_3(X,H);if(!K?.replyState)return!1;let _=K.replyState;if(W>0&&W<_.openedAt)return!1;if(_.status!=="waiting"||E4(K.notifyId))return await Q(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:G,message_id:z,prompt_message_id:_.promptMessageId},L={..._,status:"sending",response:j};K3(K.notifyId);try{try{S4(K.notifyId,L)}catch(U){return await Q(X,`回复保存失败,尚未回传,请重新输入:${Z(U)}`),!0}let q;try{try{await $.updateCard(_.promptMessageId,v1(K,L))}catch(U){throw Error(k(U))}if(K.callbackUrl)q=await $.dispatch(K,j,H);else j3(K.notifyId,void 0,H),q={ok:!0,detail:"已记录"}}catch(U){q={ok:!1,detail:Z(U)}}let D;if(q.ok){let U=K.callbackUrl?Z7(K.notifyId,void 0,H):{state:"complete"};D={kind:"text",text:G,operatorOpenId:H,status:U.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...U.state==="unknown"?{detail:U.detail}:{reply:q.reply}}}else{D={kind:"text",text:G,operatorOpenId:H,status:"failed",detail:q.detail};try{S4(K.notifyId,{...L,status:"failed",error:q.detail})}catch(U){let M=`${q.detail};失败状态保存失败:${Z(U)}`;try{$7(K.notifyId,void 0,H,M)}catch(O){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(O)}`)}D={...D,status:"unknown",detail:M}}}let F=D.status==="delivered"?"回复已送达":D.status==="done"?"回复已记录":D.status==="unknown"?`回复送达状态未知:${D.detail}`:`回复未送达:${D.detail}`;return await Y(K,_.promptMessageId,v1(K,L,D),F),await Y(K,K.messageId,f1(K,D),F),$.log(`notify-reply: notify_id=${K.notifyId} status=${D.status}`),!0}finally{B3(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var iB=R(()=>{q3();D7()});function nB($){let Z=AY($,"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=f4(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=tB(Z.prompt,'agent run requires "prompt"'),H=f4(Z.effort),z=oB(Z);return{identityIds:Q,description:h4(Z.description),prompt:X,...H?{effort:H}:{},...V?{sessionId:V}:{},...z!==void 0?{workDir:z}:{}}}function aB($){let Z=AY($,"agent follow-up request"),J=tB(Z.prompt,'agent follow-up requires "prompt"'),Q=f4(Z.identity_id??Z.identityId),Y=f4(Z.effort),V=oB(Z);return{description:h4(Z.description),prompt:J,...Q?{identityId:Q}:{},...Y?{effort:Y}:{},...V!==void 0?{workDir:V}:{}}}function OY($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function oB($){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:OY(Z)}function h4($){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 sB($){let Z=AY($,"agent answer request"),J=f4(Z.identity_id??Z.identityId),Q=f4(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 AY($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function tB($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function f4($){return(typeof $==="string"?$.trim():"")||void 0}function AN(){return["---",`name: ${rB}`,`description: ${JSON.stringify("Main Agents can delegate tasks to configured models or Agents through Lodestar, including their own model or Agent, and continue the same work across multiple turns. Delegated Agents and subagents must not use this Skill or delegate further.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Choosing a delegation method","","- The main Agent chooses between native Agent/subagent capabilities and"," `lodestar-agent` based on the task and available capabilities.","- Both methods are allowed when calling your own model or Agent.","","## Required workflow","","1. When using Lodestar, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation."," Every run and follow-up also requires `--description`: a short, user-facing"," single-line task summary (at most 60 characters). The card shows this line"," with status; the full prompt, progress and results stay collapsed.","4. For the same prompt sent to several identities, pass them to one run"," with repeated `--identity`; the daemon schedules them within concurrency limits."," OpenRouter allows at most 2 delegated tasks at once across projects and models"," in the same daemon; additional tasks queue. This is a local limit, not an API quota."," Wait for queued tasks instead of submitting duplicates. If rate-limited, report"," the error and do not immediately retry the whole batch.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","6. When the same work needs another step, review the returned content and"," continue with `run --session <session-id>` plus the new input. Use as many"," turns as the authorized task needs; assess completion against the overall"," task and its verification requirements, not just one run ending.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","### Working directory","","New tasks default to the main Agent working directory, even if the calling","shell has changed directory. Use `--workdir <path>` to select an existing","subdirectory. Relative paths are resolved from the main Agent directory;","absolute paths are also accepted within that directory. Symlinks are resolved","and paths outside the main directory, missing paths and files are rejected.","All identities in one run use the same directory; use separate runs for different directories.","","```bash","# desc: 在主 Agent 工作目录的子目录中执行任务","lodestar-agent run --identity '<identity-id>' --description '检查应用代码' --workdir 'packages/app' --prompt 'Inspect the application and report the results.'","```","","`run --session` and `follow-up` retain the original task directory. Omit","`--workdir` when continuing, or supply a path resolving to that same directory;","changing directories requires a new task. Results report `Work directory:`","(JSON: `work_dir`). The HTTP API accepts `work_dir` on run/follow-up requests.","","## Complete one work item across multiple turns","","A single work item can span multiple turns in the same native Agent session.","Use this for staged implementation, revisions based on feedback, or further","verification of previous results. The main Agent reads each result and sends","the next step; the delegated Agent still must not delegate further.","","Keep the returned `Session:` id (JSON: `workers[].session_id`) together with","the worker output. For turn 2 and later, send that id and only the new input:","","```bash","# desc: 用历史会话 ID 继续下一轮","lodestar-agent run --session '<session-id>' --description '继续下一步任务' --stdin <<'EOF'","<new input for the next turn>","EOF","```","","This resumes the provider-native conversation and inherits its identity and","last effort. An optional `--identity` must match the original worker;","`--effort` explicitly changes the effort for this turn. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","The session must belong to this Lodestar Session and workspace, with its","delegated run history still available. Saved history supports continuation","after a daemon restart. Unknown sessions, unavailable identities and native","resume failures are errors. Wait for the current run to finish before resuming;","concurrent turns on the same native session are rejected.","","Use `--json` with `run`, `follow-up` or `status` for structured results:","`workers[].session_id` is the conversation id and `workers[].output` is the","returned content. `--prompt <text>` supplies inline input instead of stdin.","A parallel run returns one session id per worker; continue each separately.","","For example, after turn 1 implements the requested change using the run form","above, continue the same work with feedback and then verification:","","```bash","# desc: 第二轮根据上一轮结果和反馈继续修改","lodestar-agent run --session '<session-id>' --description '根据反馈修改' --prompt 'Revise the previous implementation using this feedback: <specific feedback>.' --json","```","","Read turn 2's result before choosing turn 3's input, using the same session id:","","```bash","# desc: 第三轮验证同一项工作的最终结果","lodestar-agent run --session '<session-id>' --description '验证最终结果' --prompt 'Verify the revised implementation against the original requirements and report the results and any remaining issues.' --json","```","","These turns retain the earlier conversation; send only the new requirements,","feedback or next step. Omitting `--session` starts a fresh conversation.","An empty, unknown or out-of-scope session id is rejected before execution;","native resume failures are reported and never converted into a fresh session.","","If you kept the `run_id`, the existing follow-up form also resumes its worker:","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<follow-up prompt>","EOF","```","","## Answer a child question","","When a run returns `Status: needs_input`, answer the exact request id. JSON","keys may be the question id or the full question text:","","```bash","# desc: 回答 Agent 的阻塞问题并继续运行","lodestar-agent answer '<run-id>' --identity '<identity-id>' --request '<request-id>' --stdin <<'EOF'",'{"question-id":"answer"}',"EOF","```","","## Boundaries","","- Do not invoke provider CLIs or provider HTTP APIs directly for delegation.","- Never expose `LODESTAR_AGENT_CAPABILITY` in prompts, output, logs, or args.","- A non-zero command exit is a real failure. Do not claim the child succeeded.","- Scope the Agent task and authorized actions to the user request.",""].join(`
575
- `)}function $_(){U7("lodestar-consult"),F7({name:rB,body:AN()})}var rB="lodestar-agent",eB;var NY=R(()=>{M7();eB=["You are a delegated Agent working on a task assigned by the main Agent.","Complete this task yourself. You must not create or invoke any further Agents or subagents.","This includes Lodestar delegation, provider-native Agent/subagent tools, and delegation through CLIs or HTTP APIs.","If additional Agent work is needed, report the need to the main Agent so it can assign that work."].join(`
573
+ `}function lB(){F7({name:cB,body:UN(p.notify.port)})}var cB="feishu-notify";var uB=R(()=>{f0();U7()});import{randomUUID as ON}from"node:crypto";function dB($){let Z=(V)=>V instanceof Error?V.message:String(V),J=(V,X,H)=>{if(!V)return"通知已过期或已移除";if(!H)return"无法识别回复人,操作未执行";if(X&&X!==V.chatId)return"通知不属于当前群,操作未执行";if(!V.allowReply)return"此通知未开启文字回复";if(V.unknownAt)return`回复送达状态未知,禁止自动重试:${V.unknownReason}`;if(V.resolvedAt)return"此通知已处理";if(E4(V.notifyId))return"通知正在处理中";return null},Q=async(V,X)=>{$.log(`notify-reply: ${X}`);let H;if(!await $.sendText(V,`❌ ${X}`,(z)=>{H=z}))throw Error(`通知回复错误提示发送失败: ${k(H)};原错误:${X}`)},Y=async(V,X,H,z)=>{try{await $.updateCard(X,H)}catch(G){await Q(V.chatId,`${z},卡片更新失败:${k(G)}`)}};return{async recover(V){if(V.dispatchState&&V.unknownAt){let z=V.dispatchState,G=V.buttons.find((W)=>W.id===z.buttonId);await Y(V,V.messageId,f1(V,{status:"unknown",buttonId:z.buttonId,text:G?.text??z.buttonId,operatorOpenId:z.openId,detail:V.unknownReason}),"按钮回调送达状态未知");return}let X=V.replyState;if(!X||!V.unknownAt)return;let H={kind:"text",status:"unknown",text:X.response?.text??"",operatorOpenId:X.openId,detail:V.unknownReason};await Y(V,X.promptMessageId,v1(V,X,H),"回复送达状态未知"),await Y(V,V.messageId,f1(V,H),"回复送达状态未知")},async open(V,X,H){let z=Y1(V),G=J(z,X,H);if(G||!z)return{ok:!1,message:G};if(z.replyState?.status==="waiting"||z.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let W=lQ(z.chatId);if(W.some((K)=>K.replyState?.status==="sending"||E4(K.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};K3(V);try{for(let L of W){let q={...L.replyState,status:"cancelled",cancelReason:"switched"};S4(L.notifyId,q),await Y(L,q.promptMessageId,v1(L,q),"已放弃上一条回复并切换通知")}let K={id:ON(),openId:H,promptMessageId:"",openedAt:Date.now(),status:"waiting"},_,j=await $.sendCard(z.chatId,v1(z,K),(L)=>{_=L});if(!j)return{ok:!1,message:`等待输入卡片发送失败,未开始接收回复,请重新点击「回复」
574
+ ${k(_)}`};K.promptMessageId=j;try{S4(V,K)}catch(L){let q=`等待输入状态保存失败,未开始接收回复:${Z(L)}`;return await Y(z,j,v1(z,K,{status:"failed",detail:q}),q),{ok:!1,message:q,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{B3(V),$.onWaitingChanged(z.chatId)}},async cancel(V,X,H,z){let G=Y1(V),W=J(G,H,z);if(W||!G)return{ok:!1,message:W};let K=G.replyState;if(!K||K.id!==X||K.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(K.openId!==z)return{ok:!1,message:"仅点击「回复」的人可以取消"};let _={...K,status:"cancelled"};return S4(V,_),$.onWaitingChanged(G.chatId),await Y(G,K.promptMessageId,v1(G,_),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(V){let{chatId:X,openId:H,messageId:z,text:G,createTime:W}=V;if(!H||!z||!G.trim())return!1;if($K(X,z))return!0;let K=_3(X,H);if(!K?.replyState)return!1;let _=K.replyState;if(W>0&&W<_.openedAt)return!1;if(_.status!=="waiting"||E4(K.notifyId))return await Q(X,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let j={text:G,message_id:z,prompt_message_id:_.promptMessageId},L={..._,status:"sending",response:j};K3(K.notifyId);try{try{S4(K.notifyId,L)}catch(M){return await Q(X,`回复保存失败,尚未回传,请重新输入:${Z(M)}`),!0}let q;try{try{await $.updateCard(_.promptMessageId,v1(K,L))}catch(M){throw Error(k(M))}if(K.callbackUrl)q=await $.dispatch(K,j,H);else j3(K.notifyId,void 0,H),q={ok:!0,detail:"已记录"}}catch(M){q={ok:!1,detail:Z(M)}}let D;if(q.ok){let M=K.callbackUrl?Z7(K.notifyId,void 0,H):{state:"complete"};D={kind:"text",text:G,operatorOpenId:H,status:M.state==="unknown"?"unknown":K.callbackUrl?"delivered":"done",...M.state==="unknown"?{detail:M.detail}:{reply:q.reply}}}else{D={kind:"text",text:G,operatorOpenId:H,status:"failed",detail:q.detail};try{S4(K.notifyId,{...L,status:"failed",error:q.detail})}catch(M){let U=`${q.detail};失败状态保存失败:${Z(M)}`;try{$7(K.notifyId,void 0,H,U)}catch(O){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(O)}`)}D={...D,status:"unknown",detail:U}}}let F=D.status==="delivered"?"回复已送达":D.status==="done"?"回复已记录":D.status==="unknown"?`回复送达状态未知:${D.detail}`:`回复未送达:${D.detail}`;return await Y(K,_.promptMessageId,v1(K,L,D),F),await Y(K,K.messageId,f1(K,D),F),$.log(`notify-reply: notify_id=${K.notifyId} status=${D.status}`),!0}finally{B3(K.notifyId),$.onWaitingChanged(K.chatId)}}}}var iB=R(()=>{q3();D7()});function nB($){let Z=AY($,"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=f4(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=tB(Z.prompt,'agent run requires "prompt"'),H=f4(Z.effort),z=oB(Z);return{identityIds:Q,description:h4(Z.description),prompt:X,...H?{effort:H}:{},...V?{sessionId:V}:{},...z!==void 0?{workDir:z}:{}}}function aB($){let Z=AY($,"agent follow-up request"),J=tB(Z.prompt,'agent follow-up requires "prompt"'),Q=f4(Z.identity_id??Z.identityId),Y=f4(Z.effort),V=oB(Z);return{description:h4(Z.description),prompt:J,...Q?{identityId:Q}:{},...Y?{effort:Y}:{},...V!==void 0?{workDir:V}:{}}}function OY($){if(typeof $!=="string"||!$.trim()||$.includes("\x00"))throw Error("agent work_dir must be a non-empty path without null bytes");return $}function oB($){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:OY(Z)}function h4($){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 sB($){let Z=AY($,"agent answer request"),J=f4(Z.identity_id??Z.identityId),Q=f4(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 AY($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function tB($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function f4($){return(typeof $==="string"?$.trim():"")||void 0}function AN(){return["---",`name: ${rB}`,`description: ${JSON.stringify("Main Agents can delegate tasks to configured models or Agents through Lodestar, including their own model or Agent, and continue the same work across multiple turns. Delegated Agents and subagents must not use this Skill or delegate further.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Choosing a delegation method","","- The main Agent chooses between native Agent/subagent capabilities and"," `lodestar-agent` based on the task and available capabilities.","- Both methods are allowed when calling your own model or Agent.","","## Required workflow","","1. When using Lodestar, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation."," Every run and follow-up also requires `--description`: a short, user-facing"," single-line task summary (at most 60 characters). The card shows this line"," with status; the full prompt, progress and results stay collapsed.","4. For the same prompt sent to several identities, pass them to one run"," with repeated `--identity`; the daemon schedules them within concurrency limits."," OpenRouter allows at most 2 delegated tasks at once across projects and models"," in the same daemon; additional tasks queue. This is a local limit, not an API quota."," Wait for queued tasks instead of submitting duplicates. If rate-limited, report"," the error and do not immediately retry the whole batch.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","6. When the same work needs another step, review the returned content and"," continue with `run --session <session-id>` plus the new input. Use as many"," turns as the authorized task needs; assess completion against the overall"," task and its verification requirements, not just one run ending.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","### Working directory","","New tasks default to the main Agent working directory, even if the calling","shell has changed directory. Use `--workdir <path>` to select an existing","subdirectory. Relative paths are resolved from the main Agent directory;","absolute paths are also accepted within that directory. Symlinks are resolved","and paths outside the main directory, missing paths and files are rejected.","All identities in one run use the same directory; use separate runs for different directories.","","```bash","# desc: 在主 Agent 工作目录的子目录中执行任务","lodestar-agent run --identity '<identity-id>' --description '检查应用代码' --workdir 'packages/app' --prompt 'Inspect the application and report the results.'","```","","`run --session` and `follow-up` retain the original task directory. Omit","`--workdir` when continuing, or supply a path resolving to that same directory;","changing directories requires a new task. Results report `Work directory:`","(JSON: `work_dir`). The HTTP API accepts `work_dir` on run/follow-up requests.","","## Complete one work item across multiple turns","","A single work item can span multiple turns in the same native Agent session.","Use this for staged implementation, revisions based on feedback, or further","verification of previous results. The main Agent reads each result and sends","the next step; the delegated Agent still must not delegate further.","","Keep the returned `Session:` id (JSON: `workers[].session_id`) together with","the worker output. For turn 2 and later, send that id and only the new input:","","```bash","# desc: 用历史会话 ID 继续下一轮","lodestar-agent run --session '<session-id>' --description '继续下一步任务' --stdin <<'EOF'","<new input for the next turn>","EOF","```","","This resumes the provider-native conversation and inherits its identity and","last effort. An optional `--identity` must match the original worker;","`--effort` explicitly changes the effort for this turn. The run returns a new","`run_id` and the same native `session_id`; repeat to continue further turns.","The session must belong to this Lodestar Session and workspace, with its","delegated run history still available. Saved history supports continuation","after a daemon restart. Unknown sessions, unavailable identities and native","resume failures are errors. Wait for the current run to finish before resuming;","concurrent turns on the same native session are rejected.","","Use `--json` with `run`, `follow-up` or `status` for structured results:","`workers[].session_id` is the conversation id and `workers[].output` is the","returned content. `--prompt <text>` supplies inline input instead of stdin.","A parallel run returns one session id per worker; continue each separately.","","For example, after turn 1 implements the requested change using the run form","above, continue the same work with feedback and then verification:","","```bash","# desc: 第二轮根据上一轮结果和反馈继续修改","lodestar-agent run --session '<session-id>' --description '根据反馈修改' --prompt 'Revise the previous implementation using this feedback: <specific feedback>.' --json","```","","Read turn 2's result before choosing turn 3's input, using the same session id:","","```bash","# desc: 第三轮验证同一项工作的最终结果","lodestar-agent run --session '<session-id>' --description '验证最终结果' --prompt 'Verify the revised implementation against the original requirements and report the results and any remaining issues.' --json","```","","These turns retain the earlier conversation; send only the new requirements,","feedback or next step. Omitting `--session` starts a fresh conversation.","An empty, unknown or out-of-scope session id is rejected before execution;","native resume failures are reported and never converted into a fresh session.","","If you kept the `run_id`, the existing follow-up form also resumes its worker:","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --description '完成指定任务' --stdin <<'EOF'","<follow-up prompt>","EOF","```","","## Answer a child question","","When a run returns `Status: needs_input`, answer the exact request id. JSON","keys may be the question id or the full question text:","","```bash","# desc: 回答 Agent 的阻塞问题并继续运行","lodestar-agent answer '<run-id>' --identity '<identity-id>' --request '<request-id>' --stdin <<'EOF'",'{"question-id":"answer"}',"EOF","```","","## Boundaries","","- Do not invoke provider CLIs or provider HTTP APIs directly for delegation.","- Never expose `LODESTAR_AGENT_CAPABILITY` in prompts, output, logs, or args.","- A non-zero command exit is a real failure. Do not claim the child succeeded.","- Scope the Agent task and authorized actions to the user request.",""].join(`
575
+ `)}function $_(){M7("lodestar-consult"),F7({name:rB,body:AN()})}var rB="lodestar-agent",eB;var NY=R(()=>{U7();eB=["You are a delegated Agent working on a task assigned by the main Agent.","Complete this task yourself. You must not create or invoke any further Agents or subagents.","This includes Lodestar delegation, provider-native Agent/subagent tools, and delegation through CLIs or HTTP APIs.","If additional Agent work is needed, report the need to the main Agent so it can assign that work."].join(`
576
576
  `)});function Z_($){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}=u9({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,eB].filter(Boolean).join(`
577
577
 
578
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return NN(Q,$.prompt,$.callbacks)}function NN($,Z,J={},Q=ZX){let Y=[],V=null,X=!1,H=null,z=null,G=[],W,K,_=Date.now(),j=new Promise((w,N)=>{W=w,K=N}),L=(w)=>{if(!w)return null;try{return Q($.provider,w),J.onSession?.(w),null}catch(N){return N instanceof Error?N:Error(String(N))}},q=()=>{if($.off("assistant_text",F),$.off("tool_use",M),$.off("tool_result",O),$.off("subagent_step",A),$.off("can_use_tool",T),$.off("hook_callback",y),$.off("init",S),!$.isAlive())$.off("error",h);$.off("turn_retry",E),$.off("codex_account_changed",l),$.off("result",m),$.off("exit",Y0)},D=(w,N)=>{if(H)return H;return X=!0,G.length=0,H=Promise.resolve().then(async()=>{let f=L($.sessionId);try{await $.kill(3000)}catch(D$){z=D$ instanceof Error?D$:Error(String(D$))}q();let z0=[w,f,z].filter((D$)=>!!D$),n=z0.length>1?AggregateError(z0,z0.map((D$)=>D$.message).join("; ")):z0[0];if(n){K(new O3(n,Y.join("").trim(),$.sessionId));return}let T0=$.sessionId;if(!T0){K(new O3(Error("delegated agent completed without a native session id"),Y.join("").trim(),null));return}let N3=Y.join("").trim(),c4=xN(N?.checkpoint,$);W({output:N3,outputTruncated:!1,sessionId:T0,...c4?{checkpointId:c4}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),H},F=(w)=>{if(X||w?.parentToolUseId||typeof w?.text!=="string")return;Y.push(w.text)},U=(w)=>{if(X)return;try{J.onProgress?.(w)}catch(N){D(N instanceof Error?N:Error(String(N)))}},M=(w)=>U({at:new Date().toISOString(),phase:"started",tool:String(w?.name??"tool"),detail:""}),O=(w)=>U({at:new Date().toISOString(),phase:"completed",tool:w?.is_error?"tool error":"tool result",detail:""}),A=(w)=>U({at:new Date().toISOString(),phase:w?.phase??"info",tool:String(w?.tool??"subagent"),detail:""}),T=(w)=>{if(X)return;if(w.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(w.request_id,"allow",{updatedInput:w.input??{}})}catch(f){D(f instanceof Error?f:Error(String(f)))}return}let N;try{N=RN(w)}catch(f){D(f instanceof Error?f:Error(String(f)));return}if(G.some((f)=>f.request.requestId===N.requestId))return;G.push({request:N,originalInput:w.input??{}});try{if(G.length===1)J.onNeedsInput?.(N)}catch(f){D(f instanceof Error?f:Error(String(f)))}},y=(w)=>{if(X)return;try{$.sendHookResponse(String(w.request_id),{})}catch(N){D(N instanceof Error?N:Error(String(N)))}},S=(w)=>{let N=L(w?.session_id??$.sessionId);if(N)D(N)},h=(w)=>{V=w instanceof Error?w:Error(String(w))},l=(w)=>{if(X)return;try{J.onCodexAccount?.(w.accountId)}catch(N){D(N instanceof Error?N:Error(String(N)))}if(w.diagnostics.length)B(`agent-runner: selected Codex account=${w.accountId}; diagnostics: ${w.diagnostics.join(";")}`)},E=(w)=>{U({at:new Date().toISOString(),phase:"info",tool:w.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:w.phase==="waiting"?`${w.message} · ${w.delayMs/1000}s 后重试 #${w.attempt}`:`正在重试 #${w.attempt}`})},m=(w)=>{let N=w?.is_error?Error(String(w.error??w.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(N,w)},Y0=(w)=>{if(X)return;let N=`code=${w?.code??"null"} signal=${w?.signal??"null"}`;D(V??Error(`delegated agent exited before result (${N})`))};$.on("assistant_text",F),$.on("tool_use",M),$.on("tool_result",O),$.on("subagent_step",A),$.on("can_use_tool",T),$.on("hook_callback",y),$.on("init",S),$.on("error",h),$.on("turn_retry",E),$.on("codex_account_changed",l),$.on("result",m),$.on("exit",Y0);try{$.sendInitialize(),$.sendUserText(Z)}catch(w){D(w instanceof Error?w:Error(String(w)))}return{done:j,isAlive:()=>$.isAlive(),pendingInput:()=>G[0]?.request??null,answer(w,N){let f=G[0];if(!f)throw Error("delegated agent is not waiting for input");if(f.request.requestId!==w)throw Error(`delegated agent input request mismatch: expected ${f.request.requestId}`);if($.sendPermissionResponse(w,"allow",{updatedInput:{...f.originalInput,answers:N}}),G.shift(),G[0])J.onNeedsInput?.(G[0].request)},async cancel(w="delegated agent cancelled"){let N=X;if(await D(Error(w)),await j.catch(()=>{}),N){if($.isAlive())await $.kill(3000);z=null,q()}if(z)throw z}}}function RN($){let Z=$.input??{},Q=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Y,V)=>TN(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 TN($,Z){let J=$&&typeof $==="object"?$:{question:$},Q=String(J.question??J.prompt??J.title??"").trim();if(!Q)throw Error(`delegated agent input question ${Z+1} is empty`);let Y=String(J.id??Q),V=Array.isArray(J.options)?J.options.map((X)=>{if(typeof X==="string")return{label:X};let H=X&&typeof X==="object"?X:{};return{label:String(H.label??H.value??""),...H.description?{description:String(H.description)}:{}}}).filter((X)=>X.label):[];return{id:Y,...J.header?{header:String(J.header)}:{},question:Q,options:V}}function xN($,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 O3;var J_=R(()=>{yJ();Z9();Q0();NY();I();O3=class O3 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as EN,randomBytes as SN,randomUUID as CN}from"node:crypto";import{existsSync as bN,readdirSync as kN,readFileSync as j_,realpathSync as Q_,statSync as wN}from"node:fs";import{isAbsolute as yN,join as A7,relative as vN,resolve as fN,sep as hN}from"node:path";class xY{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;shuttingDown=!1;constructor($=IN){this.deps=$;this.presentation=new z3($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if(this.assertAcceptingRuns(),$.kind!=="session")throw Error(V_);if(h4(Z.description),Z.sessionId!==void 0){if(!Z.sessionId.trim())throw Error("agent session_id must be a non-empty string");if(Z.identityIds.length>1)throw Error("agent session continuation accepts at most one identity_id");let{run:Q,worker:Y}=this.requireSessionRun($,Z.sessionId,Z.identityIds[0]);return this.followUp($,Q.snapshot.runId,{identityId:Y.identityId,description:Z.description,prompt:Z.prompt,effort:Z.effort,workDir:Z.workDir})}let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if(this.assertAcceptingRuns(),$.kind!=="session")throw Error(V_);h4(J.description);let Q=this.requireMutableDescendant($,Z);if(!I4(Q.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Y=K_(Q.snapshot,J.identityId);if(Q.handles.get(Y.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Y.sessionId)throw Error(`${Y.identityName} has no resumable native session id`);let V=O7($.session.workDir,Q.snapshot.workDir);if(Q.snapshot.sessionWorkDir!==void 0&&V!==Q.snapshot.workDir)throw Error("agent work_dir changed since the original run");if(J.workDir!==void 0&&O7($.session.workDir,J.workDir)!==V)throw Error("agent session continuation must use its original work_dir");let X=J.effort??Y.effort,H=this.reserveCapacity($,1),z;try{return z=this.reserveNativeSession(Y),await this.createRun($.session,{identityIds:[Y.identityId],description:J.description,prompt:J.prompt,effort:X,workDir:V},{parentRunId:Q.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Y})}finally{z?.(),H()}}async answer($,Z,J){let Q=this.requireMutableDescendant($,Z),Y=K_(Q.snapshot,J.identityId);if(Y.status!=="needs_input"||!Y.pendingInput)throw Error(`${Y.identityName} is not waiting for input`);if(Y.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Y.pendingInput.requestId}`);let V=Q.handles.get(Y.identityId);if(!V)throw Error("waiting agent process is no longer alive; start a follow-up run");V.answer(J.requestId,J.answers);let X=V.pendingInput();if(Y.status=X?"needs_input":"running",X)Y.pendingInput=X;else delete Y.pendingInput;return delete Y.queuedReason,this.refreshNonterminalStatus(Q),this.persist(Q),await this.updateWorkerCard(Q,Y),this.readSnapshot(Q)}getRun($,Z){return this.readSnapshot(this.requireAccessibleRun($,Z))}async cancelRun($,Z,J="agent run cancelled"){let Q=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Q))return!1;return await this.cancelTree(Q,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Q=[...this.runs.values()].filter((V)=>V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Y=await Promise.allSettled(Q.map((V)=>this.cancelTree(V,J)));TY(Y)}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[H,z]=X.split("\x00");this.bumpCancellationEpoch(H,z)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Q=await Promise.allSettled([...J.map((X)=>this.cancelTree(X,$)),...[...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($)));TY([...Q,...V]);for(let X of new Set([...this.runs.values()].map((H)=>H.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 Q=O7($.workDir,Z.workDir),Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let V=$.codexAccountId(),X=this.deps.getCatalog(V),H=Z.identityIds.map((j)=>{let L=X.identities.find((D)=>D.id===j);if(!L)throw Error(`agent identity not found: ${j}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);let q=J.resumeWorker;if(q&&(L.id!==q.identityId||L.provider!==q.provider||L.tokenSourceId!==q.tokenSourceId||L.model!==q.model))throw Error("agent session identity changed; cannot resume with a different provider, source or model");return L}),z=H.map((j)=>gN(j,mN(j,Z.effort),J.resumeWorker?.sessionId)),G=`agent_${CN()}`,W={runId:G,codexAccountId:V,sessionName:$.sessionName,chatId:$.chatId,sessionWorkDir:$.workDir,workDir:Q,prompt:Z.prompt,description:h4(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:z,createdAt:new Date().toISOString()},K={snapshot:W,session:$,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set,artifactsUnloaded:!1};try{await this.presentation.add(W)}catch(j){if(this.runs.set(G,K),J.parentRunId)Y?.children.add(G);let L=`Agent 卡片初始化失败,Agent 未启动: ${n0(j)}`;for(let q of z)q.status="failed",q.error=L;throw await this.finalizeRun(K,"failed",L),await this.deps.sendTextRaw($.chatId,`❌ ${L}`),j}if(this.runs.set(G,K),J.parentRunId)Y?.children.add(G);if(this.shuttingDown||this.currentCancellationEpoch($)!==J.cancellationEpoch){K.cancelled=!0;let j="任务已在启动前取消";for(let L of K.snapshot.workers)L.status="cancelled",L.error=j,L.finishedAt=new Date().toISOString();return this.persist(K),await Promise.all(K.snapshot.workers.map((L)=>this.updateWorkerCard(K,L))),await this.finalizeRun(K,"cancelled",j),this.readSnapshot(K)}this.persist(K);for(let j of H){let L=J.resumeWorker?.sessionId;this.executeWorker(K,j,Z.prompt,L).catch((q)=>{B(`agent: run=${G} worker=${j.id} crashed: ${n0(q)}`)})}return this.readSnapshot(K)}async executeWorker($,Z,J,Q){let Y=$.snapshot.workers.find((X)=>X.identityId===Z.id);if(await this.acquireSlot(Z,(X)=>{Y.queuedReason=X,this.persist($),this.updateWorkerCard($,Y)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=SN(32).toString("base64url"),this.capabilities.set(V,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,V),Y.status="running",Y.startedAt=new Date().toISOString(),delete Y.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Y),$.cancelled)return;if(this.assertSameSession($,$.session),O7($.session.workDir,$.snapshot.workDir)!==$.snapshot.workDir)throw Error("agent work_dir changed before the worker could start");let X=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Y.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Q,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:lN(U9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x2},hostEnv:{LODESTAR_AGENT_URL:F6(p.notify.bind,p.notify.port),LODESTAR_AGENT_CAPABILITY:V,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(z)=>{if($.cancelled)return;Y.status="needs_input",Y.pendingInput=z,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Y)},onProgress:(z)=>this.recordStep($,Y,z),onCodexAccount:(z)=>{if($.cancelled)return;Y.codexAccountId=z,this.persist($)},onSession:(z)=>{if(Y.sessionId===z)return;Y.sessionId=z,this.persist($)}}});$.handles.set(Z.id,X);let H=await X.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Y.status="completed",Y.output=H.output,Y.outputTruncated=H.outputTruncated,Y.sessionId=H.sessionId,Y.checkpointId=H.checkpointId,Y.durationMs=H.durationMs,Y.usage=H.usage,Y.finishedAt=new Date().toISOString(),delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}catch(X){if(X instanceof O3){if(Y.output=X.output,Y.outputTruncated=!1,X.sessionId)Y.sessionId=X.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Y.status="failed",Y.error=n0(X),Y.finishedAt=new Date().toISOString(),Y.startedAt)Y.durationMs=Date.now()-Date.parse(Y.startedAt);delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(V)this.capabilities.delete(V);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||A3(Z.status))return;if(Z.steps.push(J),Z.steps.length>H_)Z.steps.splice(0,Z.steps.length-H_);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: ${n0(Q)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${n0(Q)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${n0(Q)}`).catch((Y)=>B(`agent: terminal failure delivery failed: ${n0(Y)}`))})}async cancelTree($,Z){let J=!I4($.snapshot.status)&&!$.cancelled||$.handles.size>0,Q=[];if(J){$.cancelled=!0;for(let V of[...$.progressTimers.keys()])this.clearProgressTimer($,V);for(let V of $.capabilityByIdentity.values())this.capabilities.delete(V);$.capabilityByIdentity.clear()}while(!0){let V=[...$.children].map((H)=>this.runs.get(H)).filter((H)=>!!H&&this.treeHasActiveRun(H));if(V.length===0)break;let X=await Promise.allSettled(V.map((H)=>this.cancelTree(H,Z)));if(Q.push(...X),X.some((H)=>H.status==="rejected"))break}if(!J){TY(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_(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: ${n0(X)}`)),V}let Y=[];for(let V of $.snapshot.workers)if(!A3(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: ${n0(Q)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Q=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
578
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return NN(Q,$.prompt,$.callbacks)}function NN($,Z,J={},Q=ZX){let Y=[],V=null,X=!1,H=null,z=null,G=[],W,K,_=Date.now(),j=new Promise((w,N)=>{W=w,K=N}),L=(w)=>{if(!w)return null;try{return Q($.provider,w),J.onSession?.(w),null}catch(N){return N instanceof Error?N:Error(String(N))}},q=()=>{if($.off("assistant_text",F),$.off("tool_use",U),$.off("tool_result",O),$.off("subagent_step",A),$.off("can_use_tool",T),$.off("hook_callback",y),$.off("init",S),!$.isAlive())$.off("error",h);$.off("turn_retry",E),$.off("codex_account_changed",l),$.off("result",m),$.off("exit",Y0)},D=(w,N)=>{if(H)return H;return X=!0,G.length=0,H=Promise.resolve().then(async()=>{let f=L($.sessionId);try{await $.kill(3000)}catch(D$){z=D$ instanceof Error?D$:Error(String(D$))}q();let z0=[w,f,z].filter((D$)=>!!D$),n=z0.length>1?AggregateError(z0,z0.map((D$)=>D$.message).join("; ")):z0[0];if(n){K(new O3(n,Y.join("").trim(),$.sessionId));return}let T0=$.sessionId;if(!T0){K(new O3(Error("delegated agent completed without a native session id"),Y.join("").trim(),null));return}let N3=Y.join("").trim(),c4=xN(N?.checkpoint,$);W({output:N3,outputTruncated:!1,sessionId:T0,...c4?{checkpointId:c4}:{},durationMs:Date.now()-_,usage:$.lastUsage?{...$.lastUsage}:null})}),H},F=(w)=>{if(X||w?.parentToolUseId||typeof w?.text!=="string")return;Y.push(w.text)},M=(w)=>{if(X)return;try{J.onProgress?.(w)}catch(N){D(N instanceof Error?N:Error(String(N)))}},U=(w)=>M({at:new Date().toISOString(),phase:"started",tool:String(w?.name??"tool"),detail:""}),O=(w)=>M({at:new Date().toISOString(),phase:"completed",tool:w?.is_error?"tool error":"tool result",detail:""}),A=(w)=>M({at:new Date().toISOString(),phase:w?.phase??"info",tool:String(w?.tool??"subagent"),detail:""}),T=(w)=>{if(X)return;if(w.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(w.request_id,"allow",{updatedInput:w.input??{}})}catch(f){D(f instanceof Error?f:Error(String(f)))}return}let N;try{N=RN(w)}catch(f){D(f instanceof Error?f:Error(String(f)));return}if(G.some((f)=>f.request.requestId===N.requestId))return;G.push({request:N,originalInput:w.input??{}});try{if(G.length===1)J.onNeedsInput?.(N)}catch(f){D(f instanceof Error?f:Error(String(f)))}},y=(w)=>{if(X)return;try{$.sendHookResponse(String(w.request_id),{})}catch(N){D(N instanceof Error?N:Error(String(N)))}},S=(w)=>{let N=L(w?.session_id??$.sessionId);if(N)D(N)},h=(w)=>{V=w instanceof Error?w:Error(String(w))},l=(w)=>{if(X)return;try{J.onCodexAccount?.(w.accountId)}catch(N){D(N instanceof Error?N:Error(String(N)))}if(w.diagnostics.length)B(`agent-runner: selected Codex account=${w.accountId}; diagnostics: ${w.diagnostics.join(";")}`)},E=(w)=>{M({at:new Date().toISOString(),phase:"info",tool:w.reason==="quota"?"Codex 额度换号":"Codex 容量重试",detail:w.phase==="waiting"?`${w.message} · ${w.delayMs/1000}s 后重试 #${w.attempt}`:`正在重试 #${w.attempt}`})},m=(w)=>{let N=w?.is_error?Error(String(w.error??w.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(N,w)},Y0=(w)=>{if(X)return;let N=`code=${w?.code??"null"} signal=${w?.signal??"null"}`;D(V??Error(`delegated agent exited before result (${N})`))};$.on("assistant_text",F),$.on("tool_use",U),$.on("tool_result",O),$.on("subagent_step",A),$.on("can_use_tool",T),$.on("hook_callback",y),$.on("init",S),$.on("error",h),$.on("turn_retry",E),$.on("codex_account_changed",l),$.on("result",m),$.on("exit",Y0);try{$.sendInitialize(),$.sendUserText(Z)}catch(w){D(w instanceof Error?w:Error(String(w)))}return{done:j,isAlive:()=>$.isAlive(),pendingInput:()=>G[0]?.request??null,answer(w,N){let f=G[0];if(!f)throw Error("delegated agent is not waiting for input");if(f.request.requestId!==w)throw Error(`delegated agent input request mismatch: expected ${f.request.requestId}`);if($.sendPermissionResponse(w,"allow",{updatedInput:{...f.originalInput,answers:N}}),G.shift(),G[0])J.onNeedsInput?.(G[0].request)},async cancel(w="delegated agent cancelled"){let N=X;if(await D(Error(w)),await j.catch(()=>{}),N){if($.isAlive())await $.kill(3000);z=null,q()}if(z)throw z}}}function RN($){let Z=$.input??{},Q=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Y,V)=>TN(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 TN($,Z){let J=$&&typeof $==="object"?$:{question:$},Q=String(J.question??J.prompt??J.title??"").trim();if(!Q)throw Error(`delegated agent input question ${Z+1} is empty`);let Y=String(J.id??Q),V=Array.isArray(J.options)?J.options.map((X)=>{if(typeof X==="string")return{label:X};let H=X&&typeof X==="object"?X:{};return{label:String(H.label??H.value??""),...H.description?{description:String(H.description)}:{}}}).filter((X)=>X.label):[];return{id:Y,...J.header?{header:String(J.header)}:{},question:Q,options:V}}function xN($,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 O3;var J_=R(()=>{yJ();Z9();Q0();NY();I();O3=class O3 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as EN,randomBytes as SN,randomUUID as CN}from"node:crypto";import{existsSync as bN,readdirSync as kN,readFileSync as j_,realpathSync as Q_,statSync as wN}from"node:fs";import{isAbsolute as yN,join as A7,relative as vN,resolve as fN,sep as hN}from"node:path";class xY{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;shuttingDown=!1;constructor($=IN){this.deps=$;this.presentation=new z3($),this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if(this.assertAcceptingRuns(),$.kind!=="session")throw Error(V_);if(h4(Z.description),Z.sessionId!==void 0){if(!Z.sessionId.trim())throw Error("agent session_id must be a non-empty string");if(Z.identityIds.length>1)throw Error("agent session continuation accepts at most one identity_id");let{run:Q,worker:Y}=this.requireSessionRun($,Z.sessionId,Z.identityIds[0]);return this.followUp($,Q.snapshot.runId,{identityId:Y.identityId,description:Z.description,prompt:Z.prompt,effort:Z.effort,workDir:Z.workDir})}let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if(this.assertAcceptingRuns(),$.kind!=="session")throw Error(V_);h4(J.description);let Q=this.requireMutableDescendant($,Z);if(!I4(Q.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Y=K_(Q.snapshot,J.identityId);if(Q.handles.get(Y.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Y.sessionId)throw Error(`${Y.identityName} has no resumable native session id`);let V=O7($.session.workDir,Q.snapshot.workDir);if(Q.snapshot.sessionWorkDir!==void 0&&V!==Q.snapshot.workDir)throw Error("agent work_dir changed since the original run");if(J.workDir!==void 0&&O7($.session.workDir,J.workDir)!==V)throw Error("agent session continuation must use its original work_dir");let X=J.effort??Y.effort,H=this.reserveCapacity($,1),z;try{return z=this.reserveNativeSession(Y),await this.createRun($.session,{identityIds:[Y.identityId],description:J.description,prompt:J.prompt,effort:X,workDir:V},{parentRunId:Q.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeWorker:Y})}finally{z?.(),H()}}async answer($,Z,J){let Q=this.requireMutableDescendant($,Z),Y=K_(Q.snapshot,J.identityId);if(Y.status!=="needs_input"||!Y.pendingInput)throw Error(`${Y.identityName} is not waiting for input`);if(Y.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Y.pendingInput.requestId}`);let V=Q.handles.get(Y.identityId);if(!V)throw Error("waiting agent process is no longer alive; start a follow-up run");V.answer(J.requestId,J.answers);let X=V.pendingInput();if(Y.status=X?"needs_input":"running",X)Y.pendingInput=X;else delete Y.pendingInput;return delete Y.queuedReason,this.refreshNonterminalStatus(Q),this.persist(Q),await this.updateWorkerCard(Q,Y),this.readSnapshot(Q)}getRun($,Z){return this.readSnapshot(this.requireAccessibleRun($,Z))}async cancelRun($,Z,J="agent run cancelled"){let Q=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Q))return!1;return await this.cancelTree(Q,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Q=[...this.runs.values()].filter((V)=>V.snapshot.sessionName===$&&V.snapshot.chatId===Z&&!V.snapshot.parentRunId&&this.treeHasActiveRun(V)),Y=await Promise.allSettled(Q.map((V)=>this.cancelTree(V,J)));TY(Y)}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[H,z]=X.split("\x00");this.bumpCancellationEpoch(H,z)}let J=[...this.runs.values()].filter((X)=>!X.snapshot.parentRunId&&this.treeHasActiveRun(X)),Q=await Promise.allSettled([...J.map((X)=>this.cancelTree(X,$)),...[...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($)));TY([...Q,...V]);for(let X of new Set([...this.runs.values()].map((H)=>H.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 Q=O7($.workDir,Z.workDir),Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let V=$.codexAccountId(),X=this.deps.getCatalog(V),H=Z.identityIds.map((j)=>{let L=X.identities.find((D)=>D.id===j);if(!L)throw Error(`agent identity not found: ${j}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);let q=J.resumeWorker;if(q&&(L.id!==q.identityId||L.provider!==q.provider||L.tokenSourceId!==q.tokenSourceId||L.model!==q.model))throw Error("agent session identity changed; cannot resume with a different provider, source or model");return L}),z=H.map((j)=>gN(j,mN(j,Z.effort),J.resumeWorker?.sessionId)),G=`agent_${CN()}`,W={runId:G,codexAccountId:V,sessionName:$.sessionName,chatId:$.chatId,sessionWorkDir:$.workDir,workDir:Q,prompt:Z.prompt,description:h4(Z.description),...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:z,createdAt:new Date().toISOString()},K={snapshot:W,session:$,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set,artifactsUnloaded:!1};try{await this.presentation.add(W)}catch(j){if(this.runs.set(G,K),J.parentRunId)Y?.children.add(G);let L=`Agent 卡片初始化失败,Agent 未启动: ${n0(j)}`;for(let q of z)q.status="failed",q.error=L;throw await this.finalizeRun(K,"failed",L),await this.deps.sendTextRaw($.chatId,`❌ ${L}`),j}if(this.runs.set(G,K),J.parentRunId)Y?.children.add(G);if(this.shuttingDown||this.currentCancellationEpoch($)!==J.cancellationEpoch){K.cancelled=!0;let j="任务已在启动前取消";for(let L of K.snapshot.workers)L.status="cancelled",L.error=j,L.finishedAt=new Date().toISOString();return this.persist(K),await Promise.all(K.snapshot.workers.map((L)=>this.updateWorkerCard(K,L))),await this.finalizeRun(K,"cancelled",j),this.readSnapshot(K)}this.persist(K);for(let j of H){let L=J.resumeWorker?.sessionId;this.executeWorker(K,j,Z.prompt,L).catch((q)=>{B(`agent: run=${G} worker=${j.id} crashed: ${n0(q)}`)})}return this.readSnapshot(K)}async executeWorker($,Z,J,Q){let Y=$.snapshot.workers.find((X)=>X.identityId===Z.id);if(await this.acquireSlot(Z,(X)=>{Y.queuedReason=X,this.persist($),this.updateWorkerCard($,Y)}),$.slotOwners.set(Z.id,Z.tokenSourceId),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let V="";try{if(V=SN(32).toString("base64url"),this.capabilities.set(V,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,V),Y.status="running",Y.startedAt=new Date().toISOString(),delete Y.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Y),$.cancelled)return;if(this.assertSameSession($,$.session),O7($.session.workDir,$.snapshot.workDir)!==$.snapshot.workDir)throw Error("agent work_dir changed before the worker could start");let X=this.deps.startWorker({identity:Z,codexAccountId:$.snapshot.codexAccountId,effort:Y.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Q,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:lN(M9($.snapshot.workDir)),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x2},hostEnv:{LODESTAR_AGENT_URL:F6(p.notify.bind,p.notify.port),LODESTAR_AGENT_CAPABILITY:V,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(z)=>{if($.cancelled)return;Y.status="needs_input",Y.pendingInput=z,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Y)},onProgress:(z)=>this.recordStep($,Y,z),onCodexAccount:(z)=>{if($.cancelled)return;Y.codexAccountId=z,this.persist($)},onSession:(z)=>{if(Y.sessionId===z)return;Y.sessionId=z,this.persist($)}}});$.handles.set(Z.id,X);let H=await X.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Y.status="completed",Y.output=H.output,Y.outputTruncated=H.outputTruncated,Y.sessionId=H.sessionId,Y.checkpointId=H.checkpointId,Y.durationMs=H.durationMs,Y.usage=H.usage,Y.finishedAt=new Date().toISOString(),delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}catch(X){if(X instanceof O3){if(Y.output=X.output,Y.outputTruncated=!1,X.sessionId)Y.sessionId=X.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Y.status="failed",Y.error=n0(X),Y.finishedAt=new Date().toISOString(),Y.startedAt)Y.durationMs=Date.now()-Date.parse(Y.startedAt);delete Y.pendingInput,this.persist($),await this.updateWorkerCard($,Y)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(V)this.capabilities.delete(V);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||A3(Z.status))return;if(Z.steps.push(J),Z.steps.length>H_)Z.steps.splice(0,Z.steps.length-H_);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: ${n0(Q)}`,B(`agent: terminal finalization failed run=${$.snapshot.runId}: ${n0(Q)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${n0(Q)}`).catch((Y)=>B(`agent: terminal failure delivery failed: ${n0(Y)}`))})}async cancelTree($,Z){let J=!I4($.snapshot.status)&&!$.cancelled||$.handles.size>0,Q=[];if(J){$.cancelled=!0;for(let V of[...$.progressTimers.keys()])this.clearProgressTimer($,V);for(let V of $.capabilityByIdentity.values())this.capabilities.delete(V);$.capabilityByIdentity.clear()}while(!0){let V=[...$.children].map((H)=>this.runs.get(H)).filter((H)=>!!H&&this.treeHasActiveRun(H));if(V.length===0)break;let X=await Promise.allSettled(V.map((H)=>this.cancelTree(H,Z)));if(Q.push(...X),X.some((H)=>H.status==="rejected"))break}if(!J){TY(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_(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: ${n0(X)}`)),V}let Y=[];for(let V of $.snapshot.workers)if(!A3(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: ${n0(Q)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,this.pruneRunArtifacts(),$.snapshot.presentationErrors?.length){let Q=$.snapshot.presentationErrors.map((V,X)=>`${X+1}. ${V}`).join(`
579
579
  `),Y=Q.length>3000?`${Q.slice(0,3000)}
580
580
  …完整错误已保存在任务记录中。`:Q;await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ 委派卡片出现更新错误 · ${$.snapshot.description??$.snapshot.runId}
581
581
  结果已保存,卡片更新期间出现 ${$.snapshot.presentationErrors.length} 个错误:
582
582
  ${Y}
583
- 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${n0(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}): ${n0(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=EN("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Q}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=B_($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(A7(g1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;D_(Z),this.deps.writeTextArtifact(A7(g1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=B_($.snapshot);if($.artifactsUnloaded)L_(Z,Z.runId,this.deps.readTextArtifact);return Z}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireSessionRun($,Z,J){let Q=[...this.runs.values()].flatMap((X)=>{if(!this.canAccess($,X)||W_(X.snapshot)!==$.session.workDir)return[];return X.snapshot.workers.filter((H)=>H.sessionId===Z&&(!J||H.identityId===J)).map((H)=>({run:X,worker:H}))});if(!Q.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Q.map(({worker:X})=>X.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Y=new Set(Q.map(({run:X})=>X.snapshot.parentRunId)),V=Q.filter(({run:X})=>!Y.has(X.snapshot.runId)).sort((X,H)=>Date.parse(H.run.snapshot.createdAt)-Date.parse(X.run.snapshot.createdAt))[0];if(!V)throw Error(`agent session history has no latest run: ${Z}`);return V}reserveNativeSession($){let Z=JSON.stringify([$.provider,$.sessionId]),J=[...this.runs.values()].some((Q)=>Q.snapshot.workers.some((Y)=>{if(Y.provider!==$.provider||Y.sessionId!==$.sessionId)return!1;let V=Q.handles.get(Y.identityId);return!A3(Y.status)||!!V&&V.isAlive?.()!==!1}));if(this.startingNativeSessions.has(Z)||J)throw Error("agent session is already running or starting; wait for the current turn to finish");return this.startingNativeSessions.add(Z),()=>{this.startingNativeSessions.delete(Z)}}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||W_($.snapshot)!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!I4($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Q=[...this.runs.values()].filter((H)=>this.sessionKey(H.snapshot.sessionName,H.snapshot.chatId)===J&&(!I4(H.snapshot.status)||H.handles.size>0)).length,Y=this.startingRunsBySession.get(J)??0;if(Q+Y>=z_)throw Error(`Session has reached ${z_} active Agent runs`);if([...this.runs.values()].reduce((H,z)=>H+z.snapshot.workers.filter((G)=>!A3(G.status)||z.handles.get(G.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>G_)throw Error(`global Agent worker limit ${G_} 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),__(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){return this.cancellationEpochBySession.get(this.sessionKey($.sessionName,$.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}tryAcquireSlot($){let Z=Y_.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=RY||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=Y_.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${RY} 个 Agent)`),new Promise((Q)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Q}))}releaseSlot($){this.activeTurns--,__(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<RY;){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(!I4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!A3(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,artifactsUnloaded:!1,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRunArtifacts()}pruneRunArtifacts(){if(this.runs.size<=X_)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&I4(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-X_))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function O7($,Z){let J=Q_($),Q=Q_(fN($,Z===void 0?".":OY(Z))),Y=vN(J,Q);if(Y===".."||Y.startsWith(`..${hN}`)||yN(Y))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!wN(Q).isDirectory())throw Error(`agent work_dir is not a directory: ${Q}`);return Y===""?$:Q}function W_($){return $.sessionWorkDir??$.workDir}function gN($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function mN($,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 K_($,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 I4($){return $==="completed"||$==="failed"||$==="cancelled"}function A3($){return $==="completed"||$==="failed"||$==="cancelled"}function B_($){return JSON.parse(JSON.stringify($))}function pN(){if(!bN(g1))return[];let $=[];for(let Z of kN(g1).filter((J)=>J.endsWith(".json")).sort()){let J=A7(g1,Z),Q;try{Q=JSON.parse(j_(J,"utf8"))}catch(Y){throw Error(`agent run artifact is unreadable (${J}): ${n0(Y)}`)}if(!cN(Q))throw Error(`agent run artifact is invalid: ${J}`);L_(Q,J),$.push(Q)}return $}function cN($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&(Z.sessionWorkDir===void 0||typeof Z.sessionWorkDir==="string")&&typeof Z.prompt==="string"&&(Z.description===void 0||typeof Z.description==="string")&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function q_($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(n0).join("; ")}`)}function TY($){if($.some((Z)=>Z.status==="rejected"))throw q_($)}function n0($){return $ instanceof Error?$.message:String($)}function lN($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function L_($,Z,J=P_){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 P_($,Z){D_($);try{return j_(A7(g1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${n0(J)}`)}}function D_($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function __($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var RY=8,Y_,V_="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",X_=512,H_=50,z_=64,G_=128,IN;var F_=R(()=>{bQ();wQ();e();f0();H7();J_();V0();v0();I();Y_=new Map([["openrouter",2]]),IN={...kQ,getCatalog:L3,startWorker:Z_,sendTextRaw:g,writeArtifact:o,writeTextArtifact:s0,readTextArtifact:P_,loadArtifacts:pN}});async function M_($,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=iN($.headers.authorization);if(!V)return Y(401,{error:"missing bearer capability"});let X=uN(Q,V);if(!X)return Y(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return Y(200,nN(await RK(X.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let W=await Q.service.startRun(X,nB(await SY($)));return Y(202,N7(W))}catch(W){return Y(409,{error:U_(W)})}let H=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!H)return Y(405,{error:"unsupported agent endpoint"});let z=dN(H[1]);if(!z)return Y(400,{error:"invalid agent run id encoding"});let G=H[2];try{if(!G&&$.method==="GET")return Y(200,N7(Q.service.getRun(X,z)));if(!G&&$.method==="DELETE"){let W=await Q.service.cancelRun(X,z,"cancelled by agent client");return Y(W?200:409,W?{ok:!0,run_id:z}:{error:"agent run is already terminal",run_id:z})}if(G==="follow-up"&&$.method==="POST"){let W=await Q.service.followUp(X,z,aB(await SY($)));return Y(202,N7(W))}if(G==="answer"&&$.method==="POST"){let W=await Q.service.answer(X,z,sB(await SY($)));return Y(200,N7(W))}}catch(W){return Y(409,{error:U_(W)})}return Y(405,{error:"unsupported agent endpoint"})}function uN($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function dN($){try{return decodeURIComponent($)}catch{return null}}function iN($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function SY($){let Z="",J=0;$.setEncoding("utf8");for await(let Q of $)if(J+=Buffer.byteLength(Q),J<=EY)Z+=Q;else Z="";if(J>EY)throw Error(`request body exceeds ${EY} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function nN($){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 N7($){return{run_id:$.runId,session_name:$.sessionName,work_dir:$.workDir,prompt:$.prompt,description:$.description,parent_run_id:$.parentRunId,parent_kind:$.parentKind,depth:$.depth,status:$.status,workers:$.workers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,provider:Z.provider,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,output_truncated:Z.outputTruncated,session_id:Z.sessionId,checkpoint_id:Z.checkpointId,pending_input:Z.pendingInput&&{request_id:Z.pendingInput.requestId,tool_use_id:Z.pendingInput.toolUseId,questions:Z.pendingInput.questions},queued_reason:Z.queuedReason,steps:Z.steps,error:Z.error,started_at:Z.startedAt,finished_at:Z.finishedAt,duration_ms:Z.durationMs,usage:Z.usage})),created_at:$.createdAt,finished_at:$.finishedAt,error:$.error,presentation_errors:$.presentationErrors,card_message_id:$.cardMessageId}}function U_($){return $ instanceof Error?$.message:String($)}var EY=4194304;var O_=R(()=>{H7()});import{chmodSync as aN,existsSync as CY,readFileSync as R_,realpathSync as oN,unlinkSync as sN}from"node:fs";import{homedir as tN}from"node:os";import{basename as rN,dirname as eN,join as h1,resolve as $R}from"node:path";function ZR($={}){let Z=oN($R($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Q=$.exists??CY,Y=eN(Z),V=h1(Y,"src","agent-cli.ts"),X=h1(Y,"lodestar-agent.js"),H=h1(Y,"dist","lodestar-agent.js"),G=/^bun(?:\.exe)?$/i.test(rN(J))?[V,X,H]:[X,H],W=G.find(Q);if(!W)throw Error(`lodestar-agent entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:W}}function T_($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??QR(Z,$.homeDir??tN(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??ZR(),V=h1(Q,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${N_(Y.runtime)}" "${N_(Y.entry)}" %*\r
583
+ 任务:${$.snapshot.runId}`).catch((V)=>B(`agent: warning delivery failed run=${$.snapshot.runId}: ${n0(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}): ${n0(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=EN("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Q}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=B_($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(A7(g1,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;D_(Z),this.deps.writeTextArtifact(A7(g1,Z),J),$.persistedArtifacts.add(Z)}readSnapshot($){let Z=B_($.snapshot);if($.artifactsUnloaded)L_(Z,Z.runId,this.deps.readTextArtifact);return Z}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireSessionRun($,Z,J){let Q=[...this.runs.values()].flatMap((X)=>{if(!this.canAccess($,X)||W_(X.snapshot)!==$.session.workDir)return[];return X.snapshot.workers.filter((H)=>H.sessionId===Z&&(!J||H.identityId===J)).map((H)=>({run:X,worker:H}))});if(!Q.length)throw Error(`agent session not found in this Session${J?" for the requested identity":""}: ${Z}`);if(new Set(Q.map(({worker:X})=>X.identityId)).size>1)throw Error("agent session id matches multiple identities; specify identity_id");let Y=new Set(Q.map(({run:X})=>X.snapshot.parentRunId)),V=Q.filter(({run:X})=>!Y.has(X.snapshot.runId)).sort((X,H)=>Date.parse(H.run.snapshot.createdAt)-Date.parse(X.run.snapshot.createdAt))[0];if(!V)throw Error(`agent session history has no latest run: ${Z}`);return V}reserveNativeSession($){let Z=JSON.stringify([$.provider,$.sessionId]),J=[...this.runs.values()].some((Q)=>Q.snapshot.workers.some((Y)=>{if(Y.provider!==$.provider||Y.sessionId!==$.sessionId)return!1;let V=Q.handles.get(Y.identityId);return!A3(Y.status)||!!V&&V.isAlive?.()!==!1}));if(this.startingNativeSessions.has(Z)||J)throw Error("agent session is already running or starting; wait for the current turn to finish");return this.startingNativeSessions.add(Z),()=>{this.startingNativeSessions.delete(Z)}}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||W_($.snapshot)!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!I4($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Q=[...this.runs.values()].filter((H)=>this.sessionKey(H.snapshot.sessionName,H.snapshot.chatId)===J&&(!I4(H.snapshot.status)||H.handles.size>0)).length,Y=this.startingRunsBySession.get(J)??0;if(Q+Y>=z_)throw Error(`Session has reached ${z_} active Agent runs`);if([...this.runs.values()].reduce((H,z)=>H+z.snapshot.workers.filter((G)=>!A3(G.status)||z.handles.get(G.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>G_)throw Error(`global Agent worker limit ${G_} 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),__(this.startingRunsBySession,J)}}sessionKey($,Z){return`${$}\x00${Z}`}currentCancellationEpoch($){return this.cancellationEpochBySession.get(this.sessionKey($.sessionName,$.chatId))??0}bumpCancellationEpoch($,Z){let J=this.sessionKey($,Z);this.cancellationEpochBySession.set(J,(this.cancellationEpochBySession.get(J)??0)+1)}tryAcquireSlot($){let Z=Y_.get($),J=this.activeTurnsBySource.get($)??0;if(this.activeTurns>=RY||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=Y_.get($.tokenSourceId);return Z(J!==void 0?`等待 ${$.tokenSourceDisplay} 执行名额(同一来源最多同时运行 ${J} 个 Agent)`:`等待执行名额(最多同时运行 ${RY} 个 Agent)`),new Promise((Q)=>this.slotWaiters.push({tokenSourceId:$.tokenSourceId,resolve:Q}))}releaseSlot($){this.activeTurns--,__(this.activeTurnsBySource,$);for(let Z=0;Z<this.slotWaiters.length&&this.activeTurns<RY;){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(!I4($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!A3(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,handles:new Map,slotOwners:new Map,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,artifactsUnloaded:!1,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRunArtifacts()}pruneRunArtifacts(){if(this.runs.size<=X_)return;let $=[...this.runs.values()].filter((Z)=>!Z.artifactsUnloaded&&Z.finalized&&!Z.finalizing&&I4(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-X_))){Z.snapshot.prompt="";for(let J of Z.snapshot.workers)J.output="";Z.artifactsUnloaded=!0}}}function O7($,Z){let J=Q_($),Q=Q_(fN($,Z===void 0?".":OY(Z))),Y=vN(J,Q);if(Y===".."||Y.startsWith(`..${hN}`)||yN(Y))throw Error("agent work_dir must be the main Agent working directory or one of its subdirectories");if(!wN(Q).isDirectory())throw Error(`agent work_dir is not a directory: ${Q}`);return Y===""?$:Q}function W_($){return $.sessionWorkDir??$.workDir}function gN($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function mN($,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 K_($,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 I4($){return $==="completed"||$==="failed"||$==="cancelled"}function A3($){return $==="completed"||$==="failed"||$==="cancelled"}function B_($){return JSON.parse(JSON.stringify($))}function pN(){if(!bN(g1))return[];let $=[];for(let Z of kN(g1).filter((J)=>J.endsWith(".json")).sort()){let J=A7(g1,Z),Q;try{Q=JSON.parse(j_(J,"utf8"))}catch(Y){throw Error(`agent run artifact is unreadable (${J}): ${n0(Y)}`)}if(!cN(Q))throw Error(`agent run artifact is invalid: ${J}`);L_(Q,J),$.push(Q)}return $}function cN($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&(Z.sessionWorkDir===void 0||typeof Z.sessionWorkDir==="string")&&typeof Z.prompt==="string"&&(Z.description===void 0||typeof Z.description==="string")&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function q_($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(n0).join("; ")}`)}function TY($){if($.some((Z)=>Z.status==="rejected"))throw q_($)}function n0($){return $ instanceof Error?$.message:String($)}function lN($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function L_($,Z,J=P_){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 P_($,Z){D_($);try{return j_(A7(g1,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${n0(J)}`)}}function D_($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function __($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var RY=8,Y_,V_="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",X_=512,H_=50,z_=64,G_=128,IN;var F_=R(()=>{bQ();wQ();e();f0();H7();J_();V0();v0();I();Y_=new Map([["openrouter",2]]),IN={...kQ,getCatalog:L3,startWorker:Z_,sendTextRaw:g,writeArtifact:o,writeTextArtifact:s0,readTextArtifact:P_,loadArtifacts:pN}});async function U_($,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=iN($.headers.authorization);if(!V)return Y(401,{error:"missing bearer capability"});let X=uN(Q,V);if(!X)return Y(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return Y(200,nN(await RK(X.session.codexAccountId())));if($.method==="POST"&&J.pathname==="/agents/runs")try{let W=await Q.service.startRun(X,nB(await SY($)));return Y(202,N7(W))}catch(W){return Y(409,{error:M_(W)})}let H=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!H)return Y(405,{error:"unsupported agent endpoint"});let z=dN(H[1]);if(!z)return Y(400,{error:"invalid agent run id encoding"});let G=H[2];try{if(!G&&$.method==="GET")return Y(200,N7(Q.service.getRun(X,z)));if(!G&&$.method==="DELETE"){let W=await Q.service.cancelRun(X,z,"cancelled by agent client");return Y(W?200:409,W?{ok:!0,run_id:z}:{error:"agent run is already terminal",run_id:z})}if(G==="follow-up"&&$.method==="POST"){let W=await Q.service.followUp(X,z,aB(await SY($)));return Y(202,N7(W))}if(G==="answer"&&$.method==="POST"){let W=await Q.service.answer(X,z,sB(await SY($)));return Y(200,N7(W))}}catch(W){return Y(409,{error:M_(W)})}return Y(405,{error:"unsupported agent endpoint"})}function uN($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function dN($){try{return decodeURIComponent($)}catch{return null}}function iN($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function SY($){let Z="",J=0;$.setEncoding("utf8");for await(let Q of $)if(J+=Buffer.byteLength(Q),J<=EY)Z+=Q;else Z="";if(J>EY)throw Error(`request body exceeds ${EY} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function nN($){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 N7($){return{run_id:$.runId,session_name:$.sessionName,work_dir:$.workDir,prompt:$.prompt,description:$.description,parent_run_id:$.parentRunId,parent_kind:$.parentKind,depth:$.depth,status:$.status,workers:$.workers.map((Z)=>({identity_id:Z.identityId,identity_name:Z.identityName,token_source_id:Z.tokenSourceId,provider:Z.provider,model:Z.model,effort:Z.effort,status:Z.status,output:Z.output,output_truncated:Z.outputTruncated,session_id:Z.sessionId,checkpoint_id:Z.checkpointId,pending_input:Z.pendingInput&&{request_id:Z.pendingInput.requestId,tool_use_id:Z.pendingInput.toolUseId,questions:Z.pendingInput.questions},queued_reason:Z.queuedReason,steps:Z.steps,error:Z.error,started_at:Z.startedAt,finished_at:Z.finishedAt,duration_ms:Z.durationMs,usage:Z.usage})),created_at:$.createdAt,finished_at:$.finishedAt,error:$.error,presentation_errors:$.presentationErrors,card_message_id:$.cardMessageId}}function M_($){return $ instanceof Error?$.message:String($)}var EY=4194304;var O_=R(()=>{H7()});import{chmodSync as aN,existsSync as CY,readFileSync as R_,realpathSync as oN,unlinkSync as sN}from"node:fs";import{homedir as tN}from"node:os";import{basename as rN,dirname as eN,join as h1,resolve as $R}from"node:path";function ZR($={}){let Z=oN($R($.daemonEntry??process.argv[1]??"")),J=$.runtime??process.execPath,Q=$.exists??CY,Y=eN(Z),V=h1(Y,"src","agent-cli.ts"),X=h1(Y,"lodestar-agent.js"),H=h1(Y,"dist","lodestar-agent.js"),G=/^bun(?:\.exe)?$/i.test(rN(J))?[V,X,H]:[X,H],W=G.find(Q);if(!W)throw Error(`lodestar-agent entry not found beside daemon: ${G.join(", ")}`);return{runtime:J,entry:W}}function T_($={}){let Z=$.platform??process.platform,J=$.env??process.env,Q=$.targetDir??QR(Z,$.homeDir??tN(),$.localAppData??process.env.LOCALAPPDATA),Y=$.launch??ZR(),V=h1(Q,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),X=Z==="win32"?`@"${N_(Y.runtime)}" "${N_(Y.entry)}" %*\r
584
584
  `:`#!/bin/sh
585
585
  exec ${A_(Y.runtime)} ${A_(Y.entry)} "$@"
586
- `,H=CY(V)?R_(V,"utf8"):null;if(H!==X)FV(V,X),B(`command: ${H===null?"installed":"updated"} ${V}`);else aN(V,448);return YR(J,Q,Z),JR(Q,Z),V}function JR($,Z){let J=h1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!CY(J))return;try{let Q=R_(J,"utf8");if(!Q.includes("lodestar-consult")&&!Q.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}sN(J),B(`command: removed obsolete ${J}`)}catch(Q){B(`command: obsolete removal failed (${J}): ${Q}`)}}function QR($,Z,J){if($==="win32")return h1(J??h1(Z,"AppData","Local"),"Lodestar","bin");return h1(Z,".local","bin")}function YR($,Z,J){let Q=J==="win32"?Object.keys($).find((H)=>H.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",V=$[Q]??"",X=(H)=>J==="win32"?H.toLowerCase():H;if(V.split(Y).some((H)=>X(H)===X(Z)))return;$[Q]=V?`${Z}${Y}${V}`:Z}function A_($){return`'${$.replaceAll("'",`'"'"'`)}'`}function N_($){return $.replaceAll('"','""')}var x_=R(()=>{I();v0()});function E_($,Z,J){return $>0&&Z-$>J}async function S_($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function C_($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function bY($){return typeof $==="string"&&$.length>0?$:void 0}function b_($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=bY(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=bY(J.file_key);if(!Q)return null;let Y=bY(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function k_($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function w_($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class kY{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 z1($){return $ instanceof Error?$.message:String($)}function y_($,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 v_($){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(U0(Y.launch,Y.routing.provider,Y.workDir),Y.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(V=await $.ensureChatForSession(Y.chatName,Y.userOpenId),!V.created)return{ok:!1,chatId:V.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(H){let z=z1(H);return $.log(`temp-session: create "${Y.chatName}" failed: ${z}`),{ok:!1,error:z}}let X=async()=>{let H=null;try{if($.registerTempSessionLease(Y.chatName,V.chatId),H=Z(V.chatId,Y.chatName),H.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(H.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${H.workDir}`);if(H.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await H.startForked(Y.launch,{announce:!1}):await H.start({announce:!1})))throw Error(`${H.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let G=z1(z);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${G}`),H)try{await H.stop("临时群启动失败清理",{announce:!1})}catch(K){let _=z1(K);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let W;try{let K=await $.disbandChatForSessionExact(Y.chatName,V.chatId);W=y_(Y.chatName,V.chatId,K)}catch(K){let _=z1(K);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(W),H?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(K){let _=z1(K);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(H){let z=z1(H);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Y,V)=>{let X=$.chatIdForSession(Y);if(!V||X!==V){let 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 H=$.registry.get(X);try{if(H)await H.stop("bye 解散",{announce:!1})}catch(G){let W=z1(G);return $.log(`temp-session: stop before disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};无法确认 Session 已停止,未执行删群`}}let z;try{let G=await $.disbandChatForSessionExact(Y,X);z=y_(Y,X,G)}catch(G){let W=z1(G);return $.log(`temp-session: disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};临时群/session 仍保留`}}try{return $.registry.delete(z),H?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(G){let W=z1(G);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${W}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${W}`}}}}}var f_=R(()=>{u1()});var TR={};import*as m4 from"@larksuiteoapi/node-sdk";import{chmodSync as VR,existsSync as yY,mkdirSync as XR,readFileSync as HR,unlinkSync as T7,writeFileSync as zR}from"node:fs";import{dirname as GR}from"node:path";function p4($,Z){if(I1=Math.max(I1,Z),R7)return R7;a0=!0,gV(),m_?.(),G1.close();for(let J of T$.values())J.closeModelSettingsChanges();try{p_?.()}catch(J){I1=1,B(`shutdown WebSocket close failed: ${J}`)}try{N2.persist()}catch(J){B(`shutdown alive marker write failed: ${J}`),I1=1}return R7=(async()=>{B(`${$}: staged shutdown begin sessions=${T$.size}`);try{let J=(async()=>{await w_(()=>[...G1.pending(),...l_,...JG()]),N2.freezeForShutdown();let X=await Promise.allSettled([x7.shutdown(`daemon ${$}`),$2.shutdown()]),H=await Promise.allSettled([jJ()]),z=await Promise.allSettled([...T$.values()].map((G)=>G.stop(`daemon ${$}`,{announce:!1})));return[...X,...H,...z]})(),Q=null,Y=new Promise((X)=>{Q=setTimeout(()=>X("deadline"),I_)}),V=await Promise.race([J.then((X)=>{for(let H of X)if(H.status==="rejected")I1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),Y]);if(Q)clearTimeout(Q);if(V==="deadline")I1=1,B(`${$}: shutdown deadline ${I_}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(J){B(`${$}: staged shutdown failed: ${J}`),I1=1}finally{c_(),process.exit(I1)}})(),R7}function vY($){return k_(l_,$)}function u_($,Z="ws"){if(a0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=KR.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 BR(){N2.persist()}function d_($,Z){return fY.sessionFor($,Z)}async function _R($){return await fY.createTempSession($)}async function jR($,Z){return await fY.disbandTempSession($,Z)}function qR($){let Z=[],J=[],Q=[],Y=typeof $?.title==="string"?$.title.trim():"";if(Y)Q.push(`# ${Y}`);let V=Array.isArray($?.content)?$.content:[];for(let X of V){if(!Array.isArray(X))continue;let H=[];for(let G of X){if(!G||typeof G!=="object")continue;switch(G.tag){case"text":{let W=String(G.text??""),K=Array.isArray(G.style)?G.style:[];if(K.includes("bold"))W=`**${W}**`;if(K.includes("italic"))W=`*${W}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))W=`~~${W}~~`;H.push(W);break}case"a":{let W=String(G.href??""),K=String(G.text??W);H.push(`[${K}](${W})`);break}case"at":{let W=String(G.user_name??G.user_id??"");H.push(`@${W}`);break}case"code_inline":H.push(`\`${String(G.text??"")}\``);break;case"hr":H.push("---");break;case"img":if(G.image_key)Z.push(String(G.image_key));break;case"media":if(G.file_key)J.push({key:String(G.file_key),name:G.file_name});break;case"emotion":break;default:if(typeof G.text==="string")H.push(G.text)}}let z=H.join("");if(z.trim())Q.push(z)}return{markdown:Q.join(`
586
+ `,H=CY(V)?R_(V,"utf8"):null;if(H!==X)FV(V,X),B(`command: ${H===null?"installed":"updated"} ${V}`);else aN(V,448);return YR(J,Q,Z),JR(Q,Z),V}function JR($,Z){let J=h1($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!CY(J))return;try{let Q=R_(J,"utf8");if(!Q.includes("lodestar-consult")&&!Q.includes("consult-cli")){B(`command: obsolete path preserved because ownership is unclear ${J}`);return}sN(J),B(`command: removed obsolete ${J}`)}catch(Q){B(`command: obsolete removal failed (${J}): ${Q}`)}}function QR($,Z,J){if($==="win32")return h1(J??h1(Z,"AppData","Local"),"Lodestar","bin");return h1(Z,".local","bin")}function YR($,Z,J){let Q=J==="win32"?Object.keys($).find((H)=>H.toLowerCase()==="path")??"Path":"PATH",Y=J==="win32"?";":":",V=$[Q]??"",X=(H)=>J==="win32"?H.toLowerCase():H;if(V.split(Y).some((H)=>X(H)===X(Z)))return;$[Q]=V?`${Z}${Y}${V}`:Z}function A_($){return`'${$.replaceAll("'",`'"'"'`)}'`}function N_($){return $.replaceAll('"','""')}var x_=R(()=>{I();v0()});function E_($,Z,J){return $>0&&Z-$>J}async function S_($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function C_($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function bY($){return typeof $==="string"&&$.length>0?$:void 0}function b_($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let X=bY(J.image_key);return X?{key:X,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Q=bY(J.file_key);if(!Q)return null;let Y=bY(J.file_name);return{key:Q,type:"file",...Y?{name:Y}:{},displayText:Y?`(${$==="media"?"video":"file"}: ${Y})`:""}}function k_($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function w_($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}class kY{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 z1($){return $ instanceof Error?$.message:String($)}function y_($,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 v_($){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(H){let z=z1(H);return $.log(`temp-session: create "${Y.chatName}" failed: ${z}`),{ok:!1,error:z}}let X=async()=>{let H=null;try{if($.registerTempSessionLease(Y.chatName,V.chatId),H=Z(V.chatId,Y.chatName),H.isRunning())return{ok:!1,error:`${Y.chatName} 已有会话在跑,先 bye 解散再重试`};if(H.workDir!==Y.workDir)throw Error(`临时群 cwd 不匹配: source=${Y.workDir} target=${H.workDir}`);if(H.applyConversationRouting(Y.routing),!(Y.launch.kind==="fork"?await H.startForked(Y.launch,{announce:!1}):await H.start({announce:!1})))throw Error(`${H.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Y.chatName,Y.seedAnchors??[],Y.branchBase),{ok:!0,chatId:V.chatId}}catch(z){let G=z1(z);if($.log(`temp-session: initialize "${Y.chatName}" failed: ${G}`),H)try{await H.stop("临时群启动失败清理",{announce:!1})}catch(K){let _=z1(K);return $.log(`temp-session: failed-create stop "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};无法确认 Session 已停止,临时群/session 仍保留: ${_}`}}if(!V.created)return{ok:!1,error:`${G};既有群保留,未执行删除`};let W;try{let K=await $.disbandChatForSessionExact(Y.chatName,V.chatId);W=y_(Y.chatName,V.chatId,K)}catch(K){let _=z1(K);return $.log(`temp-session: create cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,chatId:V.chatId,error:`${G};自动解散失败,临时群/session 仍保留: ${_}`}}try{$.registry.delete(W),H?.dispose(),$.clearSessionConversationState(Y.chatName)}catch(K){let _=z1(K);return $.log(`temp-session: local cleanup "${Y.chatName}" failed: ${_}`),{ok:!1,error:`${G};临时群已确认解散,但本地状态清理失败: ${_}`}}return{ok:!1,error:`${G};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(V.chatId,X):await X()}catch(H){let z=z1(H);return $.log(`temp-session: target actor "${Y.chatName}" failed: ${z}`),{ok:!1,chatId:V.chatId,error:`${z};临时群/session 仍保留`}}},disbandTempSession:async(Y,V)=>{let X=$.chatIdForSession(Y);if(!V||X!==V){let 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 H=$.registry.get(X);try{if(H)await H.stop("bye 解散",{announce:!1})}catch(G){let W=z1(G);return $.log(`temp-session: stop before disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};无法确认 Session 已停止,未执行删群`}}let z;try{let G=await $.disbandChatForSessionExact(Y,X);z=y_(Y,X,G)}catch(G){let W=z1(G);return $.log(`temp-session: disband "${Y}" failed: ${W}`),{ok:!1,error:`${W};临时群/session 仍保留`}}try{return $.registry.delete(z),H?.dispose(),$.clearSessionConversationState(Y),{ok:!0}}catch(G){let W=z1(G);return $.log(`temp-session: local cleanup after disband "${Y}" failed: ${W}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${W}`}}}}}var f_=R(()=>{u1()});var TR={};import*as m4 from"@larksuiteoapi/node-sdk";import{chmodSync as VR,existsSync as yY,mkdirSync as XR,readFileSync as HR,unlinkSync as T7,writeFileSync as zR}from"node:fs";import{dirname as GR}from"node:path";function p4($,Z){if(I1=Math.max(I1,Z),R7)return R7;a0=!0,gV(),m_?.(),G1.close();for(let J of T$.values())J.closeModelSettingsChanges();try{p_?.()}catch(J){I1=1,B(`shutdown WebSocket close failed: ${J}`)}try{N2.persist()}catch(J){B(`shutdown alive marker write failed: ${J}`),I1=1}return R7=(async()=>{B(`${$}: staged shutdown begin sessions=${T$.size}`);try{let J=(async()=>{await w_(()=>[...G1.pending(),...l_,...JG()]),N2.freezeForShutdown();let X=await Promise.allSettled([x7.shutdown(`daemon ${$}`),$2.shutdown()]),H=await Promise.allSettled([jJ()]),z=await Promise.allSettled([...T$.values()].map((G)=>G.stop(`daemon ${$}`,{announce:!1})));return[...X,...H,...z]})(),Q=null,Y=new Promise((X)=>{Q=setTimeout(()=>X("deadline"),I_)}),V=await Promise.race([J.then((X)=>{for(let H of X)if(H.status==="rejected")I1=1,B(`shutdown session stop failed: ${H.reason}`);return"stopped"}),Y]);if(Q)clearTimeout(Q);if(V==="deadline")I1=1,B(`${$}: shutdown deadline ${I_}ms reached; forcing exit`);else B(`${$}: all sessions stopped`)}catch(J){B(`${$}: staged shutdown failed: ${J}`),I1=1}finally{c_(),process.exit(I1)}})(),R7}function vY($){return k_(l_,$)}function u_($,Z="ws"){if(a0)return B(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Q=KR.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 BR(){N2.persist()}function d_($,Z){return fY.sessionFor($,Z)}async function _R($){return await fY.createTempSession($)}async function jR($,Z){return await fY.disbandTempSession($,Z)}function qR($){let Z=[],J=[],Q=[],Y=typeof $?.title==="string"?$.title.trim():"";if(Y)Q.push(`# ${Y}`);let V=Array.isArray($?.content)?$.content:[];for(let X of V){if(!Array.isArray(X))continue;let H=[];for(let G of X){if(!G||typeof G!=="object")continue;switch(G.tag){case"text":{let W=String(G.text??""),K=Array.isArray(G.style)?G.style:[];if(K.includes("bold"))W=`**${W}**`;if(K.includes("italic"))W=`*${W}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))W=`~~${W}~~`;H.push(W);break}case"a":{let W=String(G.href??""),K=String(G.text??W);H.push(`[${K}](${W})`);break}case"at":{let W=String(G.user_name??G.user_id??"");H.push(`@${W}`);break}case"code_inline":H.push(`\`${String(G.text??"")}\``);break;case"hr":H.push("---");break;case"img":if(G.image_key)Z.push(String(G.image_key));break;case"media":if(G.file_key)J.push({key:String(G.file_key),name:G.file_name});break;case"emotion":break;default:if(typeof G.text==="string")H.push(G.text)}}let z=H.join("");if(z.trim())Q.push(z)}return{markdown:Q.join(`
587
587
 
588
- `),imageKeys:Z,fileKeys:J}}async function PR($,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&&g4.has(V))return;if(V){if(g4.add(V),g4.size>200){let M=[...g4];g4.clear();for(let O of M.slice(-100))g4.add(O)}}let X=Number(J.create_time??0);if(E_(X,Z,LR)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)Q$(V,"CrossMark");return}let H=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?z.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{zR(E3,JSON.stringify({chat_id:H,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${H.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(O){B(`debug: seed context failed: ${O}`)}let M=G.slice(7);z.text=M,J.content=JSON.stringify(z)}let W=j0.get(H);if(!W)await A9(),W=j0.get(H);if(!W)W=await fZ(H)??void 0;if(!W){B(`unknown chat ${H}, dropping message`),await b(H,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=mZ(W);V4(K,H);let _=d_(H,K),j={};try{j=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,q="",D=!1,F=[];if(L==="text")q=(j.text??"").trim();else if(L==="post"){let M=qR(j);D=M.imageKeys.length>0||M.fileKeys.length>0,q=M.markdown.trim();for(let O of M.imageKeys){let A=await N9(J.message_id,O,"image");if(A)F.push(A)}for(let O of M.fileKeys){let A=await N9(J.message_id,O.key,"file",O.name);if(A)F.push(A)}}if(L==="text"&&q){if(await _.runCommand(q,Y,V))return}if((L==="text"||L==="post")&&q&&!D&&await S_({reply:()=>E7.consume({chatId:H,openId:Y,messageId:V??"",text:q,createTime:X,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(q,Y,V??"")}))return;if(L==="text"&&q&&await _.consumeModelCustomMessage(q,Y))return;let U=b_(L,j);if(U){let M=await N9(J.message_id,U.key,U.type,U.name);if(!M){await b(H,C_(L));return}if(F.push(M),!q&&U.displayText)q=U.displayText}if(!q&&F.length===0){B(`drop empty message ${V} type=${L}`);return}if(await _.onMultiMessageInbound(q,F,Y,V??""))return;await _.onUserMessage(q||"(empty)",F,Y,V??"")}function S7($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复"}[$]??$}function DR($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function H0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function l$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function u$($){let Z=H0($.card?P$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok,$.pending?void 0:$.message);if($.completion)Z.__modelActionCompletion=$.completion;return Z}async function A2($,Z){if(!$){B(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await g($,Z))B(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function g_($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Q=S7(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=DR(Z),H=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await K4(V,X);return}catch(j){B(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await A2(Y,`⚠️ ${Q}已处理,但原卡更新失败。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await A2(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,G=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Q}已完成`,W=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||z?.type==="error"&&!W;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await A2(Y,`${K?"❌":"✅"} ${Q}: ${G}`)}async function FR($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await A2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${S7(J)}失败: ${Q}`)}function i_($){return UR.accept($)}async function MR($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let X=String(J.notify_id??""),H=Y1(X);if(H)$.__cardActionChatId=H.chatId;if(J.kind==="notify_callback")return await OR(J,Q,Y);let z=J.kind==="notify_reply"?await E7.open(X,Q,Y):await E7.cancel(X,String(J.reply_id??""),Q,Y),G=H0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return H?l$(H,G):G}let V=T$.get(Q);if(!V)return H0({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let X=String(J.decision??"");if(!["allow","allow_always","deny"].includes(X))return{toast:{type:"error",content:"无效的权限决定"}};let H=await V.onPermissionDecision(J.request_id,X,Y);return H0({toast:{type:H.ok?X==="deny"?"error":"success":"error",content:H.message}},H.ok)}case"menu":{let X=Number(J.choice??-1);try{if(!Number.isInteger(X)||X<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${X+1})`),H0(P$(b1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(H){let z=H instanceof Error?H.message:String(H);return H0(P$(b1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return u$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return u$(X)}case"model_list_open":{let X=String(J.panel_id??""),H=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return u$(await(J.mode==="add"?V.onModelAddOpen(X,H):V.onProviderSelect(H,X)))}case"model_add":case"model_remove":case"model_custom_remove":return u$(await V.onModelListEdit(String(J.panel_id??""),String(J.source_id??""),String(J.model??""),J.kind==="model_add"?"add":J.kind==="model_remove"?"remove":"delete"));case"model_select":{let X=await V.onModelSelect(String(J.model??""),String(J.panel_id??""),Y,J);return u$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return u$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return u$(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 u$(X)}case"ask":{let X=V.askBlockReason(String(J.tool_use_id??""));if(X)return H0({toast:{type:"error",content:X}},!1);if(J.custom){let G=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",W=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,G,Y);return H0({toast:{type:W?"success":"error",content:W?"已回答":G.trim()?"问题已失效或答案未被接受":"请输入答案"}},W)}let H=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return H0({toast:{type:H?"success":"error",content:H?"已回答":"问题已失效或选项无效"}},H)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return H0(P$(X.card),X.ok)}case"temp_fork_select":{let X=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:P$(b1({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 H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:P$(b1({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 H0({toast:{type:"error",content:X.message}},X.ok);if(!X.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return H0(P$(DQ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return H0(P$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return H0(P$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return H0(P$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (_6(),B6));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return u$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Y))}return{toast:{type:"info",content:"unknown action"}}}async function OR($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=Y1(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 l$(V,H0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return l$(V,{toast:{type:"info",content:"已处理过"}});if(E4(Q))return l$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return l$(V,H0({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}"`),l$(V,H0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{j3(V.notifyId,X.id,J)}catch(G){return l$(V,H0({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)`),l$(V,{...P$(f1(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}try{rW(V.notifyId,X.id,J)}catch(G){return l$(V,H0({toast:{type:"error",content:`保存回调发送状态失败,未发送: ${G instanceof Error?G.message:G}`}},!1))}K3(V.notifyId);let H=vY(AR(V,X,J));H.catch((G)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let z=H.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return l$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:z})}async function AR($,Z,J){try{let Q=f1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await K4($.messageId,Q)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${H instanceof Error?H.message:H}`)}let Y=await uQ($,Z,J),V=Y.ok?"complete":"retry",X;if(Y.ok){let H=Z7($.notifyId,Z.id,J);if(H.state==="complete")X={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Y.reply};else{V="unknown",X={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${H.detail}`);try{await A2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${H.detail}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${z instanceof Error?z.message:z}`)}}}else{let H=eW($.notifyId);V=H.state,X={status:H.state==="retry"?"failed":"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.state==="retry"?Y.detail:`${Y.detail}; ${H.detail}`}}try{let H=f1($,X);await K4($.messageId,H)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${H instanceof Error?H.message:H}`);try{await A2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":V==="unknown"?"送达状态未知且结果卡更新失败,禁止自动重试":"已执行,但结果卡更新失败"}: ${H instanceof Error?H.message:H}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Y.detail}`} by=${J.slice(0,8)}…`),V}finally{B3($.notifyId)}}function wY($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function NR(){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(yY(m1))T7(m1)}catch{}try{Bun.serve({unix:m1,fetch:async($)=>{let Z=new URL($.url),J=$.method==="GET"&&Z.pathname==="/model-state";if($.method!=="POST"&&!J)return new Response("unsupported debug method",{status:405});if(a0)return new Response("daemon shutdown in progress",{status:503});let Q={};if($.method==="POST")try{Q=await $.json()}catch{return new Response("bad json",{status:400})}if(!yY(E3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Y={};try{Y=JSON.parse(HR(E3,"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=T$.get(Y.chat_id);return W?Response.json(UY(W)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let W=T$.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():"",_=W.modelPanels.get(K);if(!_?.messageId||_.messageId!==Q.message_id)throw Error("stale or mismatched model panel");let j=await W0.im.v1.message.get({path:{message_id:Q.message_id}});if(j.code!==0)throw Error(`message.get failed: ${k(j)}`);let L=SB(Q,Y,j.data?.items?.[0],p.feishu.app_id,_.messageId);B(`debug: model action ${Q.value.kind} chat=${Y.chat_id.slice(0,8)}…`);let q=i_(L);return await G1.enqueue(Y.chat_id,async()=>{}),Response.json({admission:q,state:UY(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 H=`【自动化测试】:${X}`,z=await b(Y.chat_id,H);if(!z)return new Response("sendText failed — see daemon log",{status:502});let G={sender:{sender_id:{open_id:Y.sender_open_id}},message:{message_id:z,chat_id:Y.chat_id,message_type:"text",content:JSON.stringify({text:X}),create_time:String(Date.now())}};if(B(`debug: inject text=${JSON.stringify(X).slice(0,80)} msg_id=${z}`),!u_(G,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Q.wait_for_handling===!0)await G1.enqueue(Y.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{VR(m1,384)}catch{}B(`debug: inject socket listening at ${m1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function RR(){B(`lodestar-daemon: pid ${process.pid} starting`),N2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (J6(),Cz));if(a0)return;$();let{refreshAllTokenSourceModels:Z,listTokenSourceAccounts:J}=await Promise.resolve().then(() => (Q0(),kX));if(a0)return;if(await Z(),await Promise.allSettled(J().map(JH)),a0)return;if(IV(),DZ(),MZ(),OZ(),NZ(),xZ(),await A9(),a0)return;setInterval(()=>{A9()},1800000);let{reconcileTasklistDeletions:Q}=await Promise.resolve().then(() => (HY(),XY));if(a0)return;try{await Q()}catch(N){B(`tasklist deletion reconcile failed: ${N instanceof Error?N.message:N}`)}if(a0)return;let Y,V=Date.now(),X=0,H=!1,z=null,G=1500,W=90000,K=600000,_=3,j=null,L=0,q="",D=!1,F=(N)=>{B(`[ws] rebuild requested before WS init — ${N}`)},U=(N,f=0,z0=!1)=>{if(a0)return;let n=Date.now()+f;if(j){if(D||=z0,n>=L){B(`[ws] rebuild already scheduled — ${N}`);return}clearTimeout(j)}L=n,q=N,D=z0,j=setTimeout(()=>{let T0=q,N3=D;j=null,L=0,q="",D=!1,F(T0,N3)},f)},M={error:(N)=>B(`[ws-sdk error] ${wY(N)}`),warn:(N)=>{let f=wY(N);if(B(`[ws-sdk warn] ${f}`),f.includes("no pong/inbound"))U("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-V<K)},info:(N)=>B(`[ws-sdk] ${wY(N)}`),debug:(N)=>{},trace:(N)=>{}},O=new m4.EventDispatcher({}),A=()=>{if(V=Date.now(),X=0,z)clearTimeout(z),z=null};O.register({"im.message.receive_v1":async(N)=>{if(A(),!u_(N))throw Error("daemon shutdown in progress")}}),O.register({"card.action.trigger":async(N)=>{return A(),i_(N)}});let T=()=>new m4.WSClient({appId:p.feishu.app_id,appSecret:p.feishu.app_secret,loggerLevel:m4.LoggerLevel.info,logger:M,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>S(),onError:(N)=>F(`SDK onError: ${N?.message??N}`)});F=(N,f=!1)=>{if(a0)return;if(H){B(`[ws] rebuild skipped (already rebuilding) — ${N}`);return}if(j)clearTimeout(j),j=null,L=0;H=!0,X++,B(`[ws] rebuild #${X} (fresh WSClient) — ${N}`);let z0=Y;try{z0?.close({force:!0})}catch(n){B(`[ws] rebuild: old close failed: ${n}`)}if(Y=T(),Y.start({eventDispatcher:O}).catch((n)=>{B(`[ws] rebuild start failed: ${n}`),U(`fresh client start failed: ${n}`,G,f)}),H=!1,f)y()};let y=()=>{if(z)clearTimeout(z);let N=Date.now();z=setTimeout(()=>{if(z=null,V>=N){X=0;return}if(X>=_){B(`[ws] STILL deaf after ${_} 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)},S=()=>{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 h=15000,l=2,E=0,m=setInterval(()=>{if(a0)return;let{state:N}=Y.getConnectionStatus();if(N==="connected"){E=0;return}if(N==="failed"||N==="idle"){E=0,F(`watchdog: state=${N}`);return}if(E++,B(`[ws] watchdog: state=${N} (${E}/${l})`),E>=l)E=0,F(`watchdog: stuck in '${N}' ~${Math.round(h*l/1000)}s`)},h);p_=()=>{if(clearInterval(m),j)clearTimeout(j);if(z)clearTimeout(z);Y.close({force:!0})};let Y0=sW();yB({bind:p.notify.bind,port:p.notify.port,extraHandler:(N,f,z0)=>M_(N,f,z0,{service:x7,authorizeSession:(n)=>{for(let T0 of T$.values())if(T0.acceptsAgentCapability(n))return T0;return null}})}),T_(),lB(),$_(),U7("lodestar-files");let w=N2.enqueue();m_=EV(B,{enabled:p.runtime.agent_auto_update}),Y.start({eventDispatcher:O}).catch((N)=>{B(`[ws] initial start failed: ${N}`),U(`initial start failed: ${N}`,G,!1)}),B(`lodestar-daemon: WS start requested, watching ${j0.size} groups`),NR();for(let N of Y0)vY(G1.enqueue(N.chatId,()=>E7.recover(N))).catch((f)=>B(`notify-reply recovery failed: ${f instanceof Error?f.message:f}`));await w}var h_=!1,a0=!1,R7=null,I1=0,m_,p_,I_=15000,c_=()=>{if(h_)return;h_=!0;try{N2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{T7(H$)}catch{}try{T7(m1)}catch{}},T$,x7,G1,N2,WR,l_,KR,fY,LR=30000,g4,E7,UR;var n_=R(()=>{H5();A8();DJ();QY();e();L$();CB();q3();D7();D7();uB();iB();F_();pZ();W6();O_();NY();M7();x_();f0();I();h2();V0();d7();s5();f_();{let $=C3(H$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(yY(H$))try{T7(H$)}catch{}}XR(GR(H$),{recursive:!0});sY(H$);process.on("exit",c_);process.on("SIGTERM",()=>{p4("SIGTERM",0)});process.on("SIGINT",()=>{p4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{p4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),p4("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),p4("uncaughtException",1)});T$=new Map,x7=new xY,G1=new P9,N2=new kY({readMarker:bZ,writeMarker:CZ,sessions:()=>T$.values(),chatIdForSession:f8,sessionFor:d_,actor:G1,isShuttingDown:()=>a0,log:B}),WR=new o5(30000),l_=new Set,KR=QH({actor:G1,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>PR($,Z)});fY=v_({registry:T$,createSession:($,Z)=>{let J=new R$($,Z,{agentCards:x7.presentation,onLifecycleChange:BR,onCreateTempSession:_R,onDisbandTempSession:jR,onCancelAgentRuns:(Q,Y,V)=>x7.cancelSessionRuns(Q,Y,V)});return N2.transferPending(J),J},ensureChatForSession:wZ,disbandChatForSessionExact:vZ,chatIdForSession:f8,clearSessionConversationState:SZ,registerTempSessionLease:FZ,hasTempSessionLease:UZ,replaceTurnAnchors:J$,runExclusive:($,Z)=>G1.enqueue($,Z),log:B});g4=new Set,E7=dB({sendCard:i,updateCard:K4,sendText:b,dispatch:uQ,onWaitingChanged:($)=>T$.get($)?.refreshPendingAsks(),log:B});UR=YH({actor:G1,deduper:WR,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=Y1(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(a0)T$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return MR($)},present:g_,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await FR($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await A2(String($?.context?.open_chat_id??""),`⚠️ ${S7(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 tV(J,(Y)=>g_($,u$(Y)));let Q=Z?.__cardActionCompletion;return Q&&typeof Q.then==="function"?Q:null},track:($)=>{vY($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${S7(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}})}});RR().catch(($)=>{B(`boot fatal: ${$}`),p4("boot fatal",1)})});V0();d7();import{existsSync as a_,unlinkSync as xR}from"node:fs";var x$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function ER(){if(!a_(w0)){if(process.stdin.isTTY){console.log(),console.log(`${x$.bold}${x$.yellow}Lodestar: 未找到配置, 启动安装向导...${x$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (hV(),fV));await Z();return}console.error(`${x$.red}Lodestar: 未找到配置 ${w0}${x$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${x$.green}lodestar-setup${x$.reset} 完成首次配置 (或直接运行 ${x$.green}lodestar-daemon${x$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=C3(H$);if($.state==="exit")console.error(`${x$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${x$.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(` • 误判 / 已经死了: 手删 ${H$} 后再跑`),process.exit(1);if(a_(H$))xR(H$);await Promise.resolve().then(() => (n_(),TR))}ER().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
588
+ `),imageKeys:Z,fileKeys:J}}async function PR($,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&&g4.has(V))return;if(V){if(g4.add(V),g4.size>200){let U=[...g4];g4.clear();for(let O of U.slice(-100))g4.add(O)}}let X=Number(J.create_time??0);if(E_(X,Z,LR)){if(B(`drop stale message ${V} ageAtReceipt=${Math.round((Z-X)/1000)}s`),V)Q$(V,"CrossMark");return}let H=J.chat_id,z={};try{z=JSON.parse(J.content??"{}")}catch{}let G=J.message_type==="text"?z.text??"":"";if(typeof G==="string"&&G.startsWith("[DEBUG]")){try{zR(E3,JSON.stringify({chat_id:H,sender_open_id:Y,seeded_at:new Date().toISOString(),seeded_msg_id:V??""},null,2)),B(`debug: seeded inject context chat=${H.slice(0,8)}… sender=${Y.slice(0,8)}…`)}catch(O){B(`debug: seed context failed: ${O}`)}let U=G.slice(7);z.text=U,J.content=JSON.stringify(z)}let W=j0.get(H);if(!W)await A9(),W=j0.get(H);if(!W)W=await fZ(H)??void 0;if(!W){B(`unknown chat ${H}, dropping message`),await b(H,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=mZ(W);V4(K,H);let _=d_(H,K),j={};try{j=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,q="",D=!1,F=[];if(L==="text")q=(j.text??"").trim();else if(L==="post"){let U=qR(j);D=U.imageKeys.length>0||U.fileKeys.length>0,q=U.markdown.trim();for(let O of U.imageKeys){let A=await N9(J.message_id,O,"image");if(A)F.push(A)}for(let O of U.fileKeys){let A=await N9(J.message_id,O.key,"file",O.name);if(A)F.push(A)}}if(L==="text"&&q){if(await _.runCommand(q,Y,V))return}if((L==="text"||L==="post")&&q&&!D&&await S_({reply:()=>E7.consume({chatId:H,openId:Y,messageId:V??"",text:q,createTime:X,parentId:J.parent_id}),hasQuestion:()=>_.hasPendingAsk(),answerQuestion:()=>_.onAskMessageAnswer(q,Y,V??"")}))return;if(L==="text"&&q&&await _.consumeModelCustomMessage(q,Y))return;let M=b_(L,j);if(M){let U=await N9(J.message_id,M.key,M.type,M.name);if(!U){await b(H,C_(L));return}if(F.push(U),!q&&M.displayText)q=M.displayText}if(!q&&F.length===0){B(`drop empty message ${V} type=${L}`);return}if(await _.onMultiMessageInbound(q,F,Y,V??""))return;await _.onUserMessage(q||"(empty)",F,Y,V??"")}function S7($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",model_page:"模型翻页",model_list_open:"模型列表",model_add:"显示模型",model_remove:"隐藏模型",model_custom_remove:"删除补录模型",model_select:"模型选择",model_custom_prompt:"模型补录",model_panel_cancel:"取消模型补录",model_effort_select:"模型 effort 选择",ask:"问题回答",worktree_disband:"worktree 解散",temp_fork_select:"会话分叉",temp_back_select:"会话回滚",temp_resume_select:"会话恢复",tasklist_enable:"启用任务清单",tasklist_delete_prompt:"删除任务清单",tasklist_delete_confirm:"确认删除任务清单",token_source_enable:"启用账号",agent_identity_page:"Agent 身份翻页",notify_callback:"通知反馈",notify_reply:"通知回复",notify_reply_cancel:"取消通知回复"}[$]??$}function DR($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function H0($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function l$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function u$($){let Z=H0($.card?P$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok,$.pending?void 0:$.message);if($.completion)Z.__modelActionCompletion=$.completion;return Z}async function A2($,Z){if(!$){B(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await g($,Z))B(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function g_($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Q=S7(J),Y=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),V=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),X=DR(Z),H=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(X&&V)try{await K4(V,X);return}catch(j){B(`card-action: ${J} original-card update failed: ${j instanceof Error?j.message:j}`),await A2(Y,`⚠️ ${Q}已处理,但原卡更新失败。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(X){await A2(Y,`⚠️ ${Q}已处理,但回调缺少原卡 message_id,无法更新。${H}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let z=Z?.toast,G=typeof z?.content==="string"&&z.content.trim()?z.content.trim():`${Q}已完成`,W=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||z?.type==="error"&&!W;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await A2(Y,`${K?"❌":"✅"} ${Q}: ${G}`)}async function FR($,Z){let J=String($?.action?.value?.kind??"unknown"),Q=Z instanceof Error?Z.message:String(Z);await A2(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${S7(J)}失败: ${Q}`)}function i_($){return MR.accept($)}async function UR($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Q=$?.context?.open_chat_id??"",Y=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let X=String(J.notify_id??""),H=Y1(X);if(H)$.__cardActionChatId=H.chatId;if(J.kind==="notify_callback")return await OR(J,Q,Y);let z=J.kind==="notify_reply"?await E7.open(X,Q,Y):await E7.cancel(X,String(J.reply_id??""),Q,Y),G=H0({toast:{type:z.ok?"success":"error",content:z.message},__cardActionPresented:z.presented===!0},z.ok);return H?l$(H,G):G}let V=T$.get(Q);if(!V)return H0({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let X=String(J.decision??"");if(!["allow","allow_always","deny"].includes(X))return{toast:{type:"error",content:"无效的权限决定"}};let H=await V.onPermissionDecision(J.request_id,X,Y);return H0({toast:{type:H.ok?X==="deny"?"error":"success":"error",content:H.message}},H.ok)}case"menu":{let X=Number(J.choice??-1);try{if(!Number.isInteger(X)||X<0)throw Error("无效的菜单选项");return await V.onUserMessage(`(menu choice ${X+1})`),H0(P$(b1({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${X+1} 项`,ok:!0})),!0)}catch(H){let z=H instanceof Error?H.message:String(H);return H0(P$(b1({title:"\uD83D\uDCCB 菜单选择",message:z,ok:!1})),!1)}}case"provider_select":{let X=await V.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return u$(X)}case"model_page":{let X=await V.onModelPage(String(J.panel_id??""),String(J.source_id??""),Number(J.page));return u$(X)}case"model_list_open":{let X=String(J.panel_id??""),H=String(J.source_id??"");if(J.mode!=="add"&&J.mode!=="select")throw Error("模型管理模式无效");return u$(await(J.mode==="add"?V.onModelAddOpen(X,H):V.onProviderSelect(H,X)))}case"model_add":case"model_remove":case"model_custom_remove":return u$(await V.onModelListEdit(String(J.panel_id??""),String(J.source_id??""),String(J.model??""),J.kind==="model_add"?"add":J.kind==="model_remove"?"remove":"delete"));case"model_select":{let X=await V.onModelSelect(String(J.model??""),String(J.panel_id??""),Y,J);return u$(X)}case"model_custom_prompt":{let X=await V.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return u$(X)}case"model_panel_cancel":{let X=await V.onModelPanelCancel(String(J.panel_id??""));return u$(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 u$(X)}case"ask":{let X=V.askBlockReason(String(J.tool_use_id??""));if(X)return H0({toast:{type:"error",content:X}},!1);if(J.custom){let G=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",W=await V.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,G,Y);return H0({toast:{type:W?"success":"error",content:W?"已回答":G.trim()?"问题已失效或答案未被接受":"请输入答案"}},W)}let H=await V.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Y);return H0({toast:{type:H?"success":"error",content:H?"已回答":"问题已失效或选项无效"}},H)}case"worktree_disband":{let X=await V.onWorktreeDisband(String(J.slug??""));return H0(P$(X.card),X.ok)}case"temp_fork_select":{let X=await V.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Y);return H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:P$(b1({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 H0(X.replaceCard===!1?{toast:{type:"error",content:X.message}}:P$(b1({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 H0({toast:{type:"error",content:X.message}},X.ok);if(!X.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return H0(P$(DQ({...X.resumePresentation,message:X.message,ok:X.ok})),X.ok,X.message)}case"tasklist_enable":{let X=await V.onTasklistEnable();return H0(P$(X.card),X.ok)}case"tasklist_delete_prompt":{let X=V.onTasklistDeletePrompt(String(J.guid??""));return H0(P$(X.card),X.ok)}case"tasklist_delete_confirm":{let X=await V.onTasklistDeleteConfirm(String(J.guid??""));return H0(P$(X.card),X.ok)}case"token_source_enable":{let{onTokenSourceEnable:X}=await Promise.resolve().then(() => (_6(),B6));return await X(V,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return u$(V.onAgentIdentityPage(String(J.panel_id??""),J.page,Y))}return{toast:{type:"info",content:"unknown action"}}}async function OR($,Z,J){let Q=String($?.notify_id??""),Y=String($?.button_id??"");if(!Q)return{toast:{type:"error",content:"回调缺少 notify_id"}};let V=Y1(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 l$(V,H0({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${V.unknownReason?`: ${V.unknownReason}`:""}`}},!0));if(V.resolvedAt)return l$(V,{toast:{type:"info",content:"已处理过"}});if(E4(Q))return l$(V,{toast:{type:"info",content:"处理中…"}});if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return l$(V,H0({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}"`),l$(V,H0({toast:{type:"error",content:"未知按钮"}},!1));if(!V.callbackUrl){try{j3(V.notifyId,X.id,J)}catch(G){return l$(V,H0({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)`),l$(V,{...P$(f1(V,{status:"done",buttonId:X.id,text:X.text,operatorOpenId:J}))})}try{rW(V.notifyId,X.id,J)}catch(G){return l$(V,H0({toast:{type:"error",content:`保存回调发送状态失败,未发送: ${G instanceof Error?G.message:G}`}},!1))}K3(V.notifyId);let H=vY(AR(V,X,J));H.catch((G)=>{B(`notify-callback: notify_id=${V.notifyId.slice(0,12)}… phase-2 rejected: ${G instanceof Error?G.message:G}`)});let z=H.then((G)=>G==="retry"?"retry":"complete").catch(()=>"retry");return l$(V,{toast:{type:"info",content:`⏳ 已选择:${X.text} · 推送中…`},__cardActionCompletion:z})}async function AR($,Z,J){try{let Q=f1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await K4($.messageId,Q)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${H instanceof Error?H.message:H}`)}let Y=await uQ($,Z,J),V=Y.ok?"complete":"retry",X;if(Y.ok){let H=Z7($.notifyId,Z.id,J);if(H.state==="complete")X={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Y.reply};else{V="unknown",X={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.detail},B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${H.detail}`);try{await A2($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${H.detail}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${z instanceof Error?z.message:z}`)}}}else{let H=eW($.notifyId);V=H.state,X={status:H.state==="retry"?"failed":"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:H.state==="retry"?Y.detail:`${Y.detail}; ${H.detail}`}}try{let H=f1($,X);await K4($.messageId,H)}catch(H){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${H instanceof Error?H.message:H}`);try{await A2($.chatId,`⚠️ 通知反馈${V==="retry"?"失败且结果卡更新失败,可重新点击":V==="unknown"?"送达状态未知且结果卡更新失败,禁止自动重试":"已执行,但结果卡更新失败"}: ${H instanceof Error?H.message:H}`)}catch(z){B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${z instanceof Error?z.message:z}`)}}return B(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${V==="complete"?"delivered":V==="unknown"?"unknown/non-retryable":`failed: ${Y.detail}`} by=${J.slice(0,8)}…`),V}finally{B3($.notifyId)}}function wY($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function NR(){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(yY(m1))T7(m1)}catch{}try{Bun.serve({unix:m1,fetch:async($)=>{let Z=new URL($.url),J=$.method==="GET"&&Z.pathname==="/model-state";if($.method!=="POST"&&!J)return new Response("unsupported debug method",{status:405});if(a0)return new Response("daemon shutdown in progress",{status:503});let Q={};if($.method==="POST")try{Q=await $.json()}catch{return new Response("bad json",{status:400})}if(!yY(E3))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let Y={};try{Y=JSON.parse(HR(E3,"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=T$.get(Y.chat_id);return W?Response.json(MY(W)):new Response("send md to open a model panel first",{status:404})}if(Z.pathname==="/model-action"){let W=T$.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():"",_=W.modelPanels.get(K);if(!_?.messageId||_.messageId!==Q.message_id)throw Error("stale or mismatched model panel");let j=await W0.im.v1.message.get({path:{message_id:Q.message_id}});if(j.code!==0)throw Error(`message.get failed: ${k(j)}`);let L=SB(Q,Y,j.data?.items?.[0],p.feishu.app_id,_.messageId);B(`debug: model action ${Q.value.kind} chat=${Y.chat_id.slice(0,8)}…`);let q=i_(L);return await G1.enqueue(Y.chat_id,async()=>{}),Response.json({admission:q,state:MY(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 H=`【自动化测试】:${X}`,z=await b(Y.chat_id,H);if(!z)return new Response("sendText failed — see daemon log",{status:502});let G={sender:{sender_id:{open_id:Y.sender_open_id}},message:{message_id:z,chat_id:Y.chat_id,message_type:"text",content:JSON.stringify({text:X}),create_time:String(Date.now())}};if(B(`debug: inject text=${JSON.stringify(X).slice(0,80)} msg_id=${z}`),!u_(G,"debug"))return new Response("daemon shutdown in progress",{status:503});if(Q.wait_for_handling===!0)await G1.enqueue(Y.chat_id,async()=>{});return new Response(JSON.stringify({ok:!0,msg_id:z}),{headers:{"content-type":"application/json"}})}});try{VR(m1,384)}catch{}B(`debug: inject socket listening at ${m1}`)}catch($){B(`debug: socket bind failed: ${$}`)}}async function RR(){B(`lodestar-daemon: pid ${process.pid} starting`),N2.load();let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (J6(),Cz));if(a0)return;$();let{refreshAllTokenSourceModels:Z,listTokenSourceAccounts:J}=await Promise.resolve().then(() => (Q0(),kX));if(a0)return;if(await Z(),await Promise.allSettled(J().map(JH)),a0)return;if(IV(),DZ(),UZ(),OZ(),NZ(),xZ(),await A9(),a0)return;setInterval(()=>{A9()},1800000);let{reconcileTasklistDeletions:Q}=await Promise.resolve().then(() => (HY(),XY));if(a0)return;try{await Q()}catch(N){B(`tasklist deletion reconcile failed: ${N instanceof Error?N.message:N}`)}if(a0)return;let Y,V=Date.now(),X=0,H=!1,z=null,G=1500,W=90000,K=600000,_=3,j=null,L=0,q="",D=!1,F=(N)=>{B(`[ws] rebuild requested before WS init — ${N}`)},M=(N,f=0,z0=!1)=>{if(a0)return;let n=Date.now()+f;if(j){if(D||=z0,n>=L){B(`[ws] rebuild already scheduled — ${N}`);return}clearTimeout(j)}L=n,q=N,D=z0,j=setTimeout(()=>{let T0=q,N3=D;j=null,L=0,q="",D=!1,F(T0,N3)},f)},U={error:(N)=>B(`[ws-sdk error] ${wY(N)}`),warn:(N)=>{let f=wY(N);if(B(`[ws-sdk warn] ${f}`),f.includes("no pong/inbound"))M("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-V<K)},info:(N)=>B(`[ws-sdk] ${wY(N)}`),debug:(N)=>{},trace:(N)=>{}},O=new m4.EventDispatcher({}),A=()=>{if(V=Date.now(),X=0,z)clearTimeout(z),z=null};O.register({"im.message.receive_v1":async(N)=>{if(A(),!u_(N))throw Error("daemon shutdown in progress")}}),O.register({"card.action.trigger":async(N)=>{return A(),i_(N)}});let T=()=>new m4.WSClient({appId:p.feishu.app_id,appSecret:p.feishu.app_secret,loggerLevel:m4.LoggerLevel.info,logger:U,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>B("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>S(),onError:(N)=>F(`SDK onError: ${N?.message??N}`)});F=(N,f=!1)=>{if(a0)return;if(H){B(`[ws] rebuild skipped (already rebuilding) — ${N}`);return}if(j)clearTimeout(j),j=null,L=0;H=!0,X++,B(`[ws] rebuild #${X} (fresh WSClient) — ${N}`);let z0=Y;try{z0?.close({force:!0})}catch(n){B(`[ws] rebuild: old close failed: ${n}`)}if(Y=T(),Y.start({eventDispatcher:O}).catch((n)=>{B(`[ws] rebuild start failed: ${n}`),M(`fresh client start failed: ${n}`,G,f)}),H=!1,f)y()};let y=()=>{if(z)clearTimeout(z);let N=Date.now();z=setTimeout(()=>{if(z=null,V>=N){X=0;return}if(X>=_){B(`[ws] STILL deaf after ${_} 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)},S=()=>{let N=Date.now()-V<K;B("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${N})`),X=0,M("post-reconnect precaution",G,N)};Y=T();let h=15000,l=2,E=0,m=setInterval(()=>{if(a0)return;let{state:N}=Y.getConnectionStatus();if(N==="connected"){E=0;return}if(N==="failed"||N==="idle"){E=0,F(`watchdog: state=${N}`);return}if(E++,B(`[ws] watchdog: state=${N} (${E}/${l})`),E>=l)E=0,F(`watchdog: stuck in '${N}' ~${Math.round(h*l/1000)}s`)},h);p_=()=>{if(clearInterval(m),j)clearTimeout(j);if(z)clearTimeout(z);Y.close({force:!0})};let Y0=sW();yB({bind:p.notify.bind,port:p.notify.port,extraHandler:(N,f,z0)=>U_(N,f,z0,{service:x7,authorizeSession:(n)=>{for(let T0 of T$.values())if(T0.acceptsAgentCapability(n))return T0;return null}})}),T_(),lB(),$_(),M7("lodestar-files");let w=N2.enqueue();m_=EV(B,{enabled:p.runtime.agent_auto_update}),Y.start({eventDispatcher:O}).catch((N)=>{B(`[ws] initial start failed: ${N}`),M(`initial start failed: ${N}`,G,!1)}),B(`lodestar-daemon: WS start requested, watching ${j0.size} groups`),NR();for(let N of Y0)vY(G1.enqueue(N.chatId,()=>E7.recover(N))).catch((f)=>B(`notify-reply recovery failed: ${f instanceof Error?f.message:f}`));await w}var h_=!1,a0=!1,R7=null,I1=0,m_,p_,I_=15000,c_=()=>{if(h_)return;h_=!0;try{N2.persist()}catch($){B(`alive marker write failed: ${$}`)}try{T7(H$)}catch{}try{T7(m1)}catch{}},T$,x7,G1,N2,WR,l_,KR,fY,LR=30000,g4,E7,MR;var n_=R(()=>{H5();A8();DJ();QY();e();L$();CB();q3();D7();D7();uB();iB();F_();pZ();W6();O_();NY();U7();x_();f0();I();h2();V0();d7();s5();f_();{let $=C3(H$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(yY(H$))try{T7(H$)}catch{}}XR(GR(H$),{recursive:!0});sY(H$);process.on("exit",c_);process.on("SIGTERM",()=>{p4("SIGTERM",0)});process.on("SIGINT",()=>{p4("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{p4("SIGBREAK",0)});process.on("unhandledRejection",($)=>{B(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),p4("unhandledRejection",1)});process.on("uncaughtException",($)=>{B(`uncaughtException: ${$.stack??$.message}`),p4("uncaughtException",1)});T$=new Map,x7=new xY,G1=new P9,N2=new kY({readMarker:bZ,writeMarker:CZ,sessions:()=>T$.values(),chatIdForSession:f8,sessionFor:d_,actor:G1,isShuttingDown:()=>a0,log:B}),WR=new o5(30000),l_=new Set,KR=QH({actor:G1,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>PR($,Z)});fY=v_({registry:T$,createSession:($,Z)=>{let J=new R$($,Z,{agentCards:x7.presentation,onLifecycleChange:BR,onCreateTempSession:_R,onDisbandTempSession:jR,onCancelAgentRuns:(Q,Y,V)=>x7.cancelSessionRuns(Q,Y,V)});return N2.transferPending(J),J},ensureChatForSession:wZ,disbandChatForSessionExact:vZ,chatIdForSession:f8,clearSessionConversationState:SZ,registerTempSessionLease:FZ,hasTempSessionLease:MZ,replaceTurnAnchors:J$,runExclusive:($,Z)=>G1.enqueue($,Z),log:B});g4=new Set,E7=dB({sendCard:i,updateCard:K4,sendText:b,dispatch:uQ,onWaitingChanged:($)=>T$.get($)?.refreshPendingAsks(),log:B});MR=YH({actor:G1,deduper:WR,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=Y1(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:($)=>{if(a0)T$.get(String($?.context?.open_chat_id??""))?.closeModelSettingsChanges();return UR($)},present:g_,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await FR($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");B(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await A2(String($?.context?.open_chat_id??""),`⚠️ ${S7(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 tV(J,(Y)=>g_($,u$(Y)));let Q=Z?.__cardActionCompletion;return Q&&typeof Q.then==="function"?Q:null},track:($)=>{vY($)},onBackgroundError:($)=>{B(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${S7(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}})}});RR().catch(($)=>{B(`boot fatal: ${$}`),p4("boot fatal",1)})});V0();d7();import{existsSync as a_,unlinkSync as xR}from"node:fs";var x$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function ER(){if(!a_(w0)){if(process.stdin.isTTY){console.log(),console.log(`${x$.bold}${x$.yellow}Lodestar: 未找到配置, 启动安装向导...${x$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (hV(),fV));await Z();return}console.error(`${x$.red}Lodestar: 未找到配置 ${w0}${x$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${x$.green}lodestar-setup${x$.reset} 完成首次配置 (或直接运行 ${x$.green}lodestar-daemon${x$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=C3(H$);if($.state==="exit")console.error(`${x$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${x$.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(` • 误判 / 已经死了: 手删 ${H$} 后再跑`),process.exit(1);if(a_(H$))xR(H$);await Promise.resolve().then(() => (n_(),TR))}ER().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});