@leviyuan/lodestar 0.16.5 → 0.16.6

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 +264 -173
  2. package/package.json +2 -2
package/dist/lodestar.js CHANGED
@@ -1,40 +1,40 @@
1
1
  #!/usr/bin/env node
2
- var xH=Object.defineProperty;var CH=($)=>$;function bH($,Z){this[$]=CH.bind(null,Z)}var G1=($,Z)=>{for(var J in Z)xH($,J,{get:Z[J],enumerable:!0,configurable:!0,set:bH.bind(Z,J)})};var S=($,Z)=>()=>($&&(Z=$($=0)),Z);import{homedir as fH}from"node:os";import{join as p}from"node:path";function u5($,Z,J){if($)return $;if(Z)return p(Z,"lodestar");return J}function wH(){if(m5)return p(process.env.APPDATA??p(a2,"AppData","Roaming"),"Lodestar");return p(a2,".config","lodestar")}function vH(){if(m5)return p(process.env.LOCALAPPDATA??p(a2,"AppData","Local"),"Lodestar");return p(a2,".local","share","lodestar")}var a2,m5,Z9,d,q$,N$,A1,J9,Y9,Q9,W9,H9,o2,y0,r2,x0,p5,l5,t2,X9,C0,s2;var R$=S(()=>{a2=fH(),m5=process.platform==="win32";Z9=u5(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,wH()),d=u5(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,vH()),q$=process.env.LODESTAR_CONFIG??p(Z9,"config.toml"),N$=p(d,"daemon.pid"),A1=p(d,"daemon.log"),J9=p(d,"session-chat-map.json"),Y9=p(d,"session-resume-map.json"),Q9=p(d,"session-turns-map.json"),W9=p(d,"session-model-map.json"),H9=p(d,"temp-session-leases.json"),o2=p(d,"tasklist-map.json"),y0=p(d,"agent-runs"),r2=p(d,"agent-session-ids.json"),x0=p(d,"managed-claude-plugin"),p5=p(d,"context-window-cache.json"),l5=p(d,"notify-callbacks.json"),t2=p(d,"alive-on-shutdown.json"),X9=p(d,"inbox"),C0=p(d,"debug.sock"),s2=p(d,"debug-context.json")});import{execSync as i5}from"node:child_process";import{readFileSync as d5,writeFileSync as hH}from"node:fs";function gH(){return process.argv[1]??`pid:${process.pid}`}function IH($){try{if(process.platform==="linux")return d5(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return i5(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return i5(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function cH($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=IH($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function e2($){let Z="";try{Z=d5($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
- `),Y=parseInt((J[0]??"").trim(),10),Q=(J[1]??"").trim();if(!Number.isFinite(Y)||Y<=0)return{state:"continue"};if(!Q)try{return process.kill(Y,0),{state:"exit",pid:Y}}catch{return{state:"continue"}}if(cH(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function n5($){hH($,`${process.pid}
4
- ${gH()}`)}var V9=()=>{};import{chmodSync as mH,closeSync as z9,fsyncSync as a5,mkdirSync as uH,openSync as o5,renameSync as pH,unlinkSync as lH,writeFileSync as iH}from"node:fs";import{randomUUID as dH}from"node:crypto";import{dirname as r5}from"node:path";function rH($){let Z=r5($);uH(Z,{recursive:!0,mode:oH})}function t5($,Z,J){rH($);let Y=`${$}.${process.pid}.${dH()}.tmp`,Q=null;try{Q=o5(Y,"wx",J),iH(Q,Z),a5(Q),z9(Q),Q=null,pH(Y,$);try{mH($,J)}catch{}if(process.platform!=="win32"){let W=null;try{W=o5(r5($),"r"),a5(W)}catch{}finally{if(W!==null)try{z9(W)}catch{}}}}catch(W){if(Q!==null)try{z9(Q)}catch{}try{lH(Y)}catch{}throw W}}function h$($,Z){t5($,Z,nH)}function s5($,Z){t5($,Z,aH)}function H$($,Z){h$($,JSON.stringify(Z,null,2)+`
5
- `)}var nH=384,aH=448,oH=448;var g$=()=>{};var JZ={};G1(JZ,{runSetup:()=>KX});import{execSync as tH,spawn as _1}from"node:child_process";import{existsSync as J4,mkdirSync as ZZ,readFileSync as sH}from"node:fs";import{createInterface as eH}from"node:readline/promises";import{delimiter as $X,dirname as ZX,join as Y4}from"node:path";import{homedir as JX}from"node:os";import{fileURLToPath as YX}from"node:url";async function b0($,Z={}){while(!0){let J=Z.default?`${_.dim} [${Z.default}]${_.reset}`:"",Y=(await K1.question(`${_.cyan}? ${_.reset}${$}${J}
6
- ${_.green}>${_.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${_.red}必填,请重新输入${_.reset}`);continue}return Y}}function QX($){let Z="═".repeat(58);console.log(`
7
- ${_.bold}${_.cyan}╔${Z}╗${_.reset}`),console.log(`${_.bold}${_.cyan}║ ${$.padEnd(54)} ║${_.reset}`),console.log(`${_.bold}${_.cyan}╚${Z}╝${_.reset}
8
- `)}function $4($,Z,J){console.log(`
9
- ${_.bold}${_.yellow}[${$}/${Z}] ${J}${_.reset}
10
- `)}function G9($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function Z4($){let Z=process.env.PATH??"";if(!Z)return null;let J=process.platform==="win32"?[`${$}.cmd`,`${$}.bat`,`${$}.exe`,$]:[$];for(let Y of Z.split($X)){if(!Y)continue;for(let Q of J){let W=Y4(Y,Q);if(J4(W))return W}}return null}function e5($){let Z=process.platform==="win32"?"npm.cmd":"npm";return new Promise((J)=>{let Y=_1(Z,["install","-g",`${$}@latest`],{stdio:"inherit",shell:process.platform==="win32"});Y.on("exit",(Q)=>J(Q===0)),Y.on("error",()=>J(!1))})}function $Z($){try{let Z=tH(`"${$}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function WX($){return new Promise((Z)=>{let J=_1($,["login"],{stdio:"inherit",shell:process.platform==="win32"});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function HX(){return process.env.CLAUDE_CONFIG_DIR||Y4(JX(),".claude")}async function XX($){try{let Z=await fetch("https://open.bigmodel.cn/api/anthropic/v1/models",{headers:{Authorization:`Bearer ${$}`},signal:AbortSignal.timeout(1e4)});if(!Z.ok)return null;let J=await Z.json(),Y=(Array.isArray(J?.data)?J.data:[]).map((K)=>typeof K?.display_name==="string"&&K.display_name?K.display_name:String(K?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(K)=>{let B=K.match(/(\d+(?:\.\d+)?)/);return B?Number(B[1]):-1},W=(K)=>K.replace(/-Turbo|-Air$/i,""),X=[...Y.filter((K)=>!/-Turbo|-Air/i.test(K))].sort((K,B)=>Q(B)-Q(K)),V=X[0],z=X[X.length-1],A={};if(V)A.ANTHROPIC_DEFAULT_OPUS_MODEL=`${V}[1m]`,A.ANTHROPIC_DEFAULT_SONNET_MODEL=`${V}[1m]`;if(z&&W(z)!==W(V))A.ANTHROPIC_DEFAULT_HAIKU_MODEL=z;return Object.keys(A).length?A:null}catch{return null}}async function VX($){try{let Z=HX();ZZ(Z,{recursive:!0});let J=Y4(Z,"settings.json"),Y={};if(J4(J)){let X=sH(J,"utf8");try{let V=JSON.parse(X);if(!V||typeof V!=="object"||Array.isArray(V))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Y=V}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Q=Y.env&&typeof Y.env==="object"&&!Array.isArray(Y.env)?Y.env:{},W={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await XX($);if(H)Object.assign(W,H);return Y.env={...Q,...W},h$(J,JSON.stringify(Y,null,2)+`
11
- `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function zX($){try{if(process.platform==="win32")_1(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")_1("open",[$],{detached:!0,stdio:"ignore"}).unref();else _1("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function GX($,Z){try{let Y=await(await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:$,app_secret:Z}),signal:AbortSignal.timeout(15000)})).json();if(Y.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Y.code} msg=${Y.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function AX(){try{let $=ZX(YX(import.meta.url)),Z=Y4($,"lodestar.js");if(!J4(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=_1(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function KX(){if(!process.stdin.isTTY)console.error(`${_.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${_.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(J4(q$)){if(console.log(`${_.yellow}发现已有配置: ${q$}${_.reset}`),(await b0("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),K1.close();return}}QX("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${_.yellow}⚠ Claude 官方限制:${_.reset}`),console.log(` ${_.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${_.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${_.dim}1) 确保 Claude Code CLI 已装好${_.reset}`),console.log(` ${_.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${_.reset}`),console.log(` ${_.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${_.reset}`),console.log(` ${_.dim}4) 工作目录, 自动启动 daemon${_.reset}`),console.log(),await K1.question(`${_.dim}按 Enter 开始 (Ctrl+C 退出)...${_.reset}`),$4(1,4,"准备 Claude Code CLI");let $=Z4("claude");if($)console.log(`${_.green}✓ claude CLI 已就位${_.reset}: ${_.dim}${$}${_.reset}`);else{if(console.log(`${_.yellow}未在 PATH 找到 claude CLI, 自动安装...${_.reset}`),console.log(`${_.dim}运行: npm install -g @anthropic-ai/claude-code@latest${_.reset}`),console.log(),!await e5("@anthropic-ai/claude-code"))console.error(`
12
- ${_.red}安装失败。${_.reset}`),console.error("请手动运行后再开向导:"),console.error(` ${_.cyan}npm install -g @anthropic-ai/claude-code@latest${_.reset}`),console.error(` ${_.cyan}lodestar-setup${_.reset}`),K1.close(),process.exit(1);$=Z4("claude"),console.log(`${_.green}✓ 安装完成${_.reset}: ${_.dim}${$??"(应该装好了, 但 PATH 找不到 — 重开终端再试)"}${_.reset}`)}console.log(),console.log(`${_.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${_.reset}`),console.log(`${_.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${_.reset}`),$4(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${_.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${_.reset}`),console.log(` ${_.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${_.reset}`),console.log();let Z=await b0("GLM API key (直接回车跳过)",{});if(Z){let B=await VX(Z);if("path"in B)console.log(`${_.green}✓ GLM 路由已写入${_.reset}: ${_.dim}${B.path}${_.reset}`),console.log(`${_.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${_.reset}`);else console.log(`${_.red}✗ 写入失败:${_.reset} ${B.error}`),console.log(`${_.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${_.reset}`)}else console.log(`${_.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${_.reset}`);if(console.log(),console.log(`${_.bold}Codex (可选第二后端)${_.reset}`),console.log(` ${_.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${_.reset}`),(await b0("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){let B=Z4("codex");if(!B){if(console.log(`${_.dim}未找到 codex CLI, 安装 @openai/codex...${_.reset}`),await e5("@openai/codex"))B=Z4("codex")}if(B&&$Z(B))console.log(`${_.green}✓ Codex 已登录 ChatGPT${_.reset}`);else if(B)if(console.log(`${_.dim}启动 \`codex login\`...${_.reset}`),await WX(B)&&$Z(B))console.log(`${_.green}✓ Codex 已登录 ChatGPT${_.reset}`);else console.log(`${_.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${_.reset}`);else console.log(`${_.yellow}Codex 安装失败 — 不影响默认 Claude 后端; 需要时手动 npm i -g @openai/codex。${_.reset}`)}else console.log(`${_.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${_.reset}`);$4(3,4,"Feishu 自建应用");let Y="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${_.cyan}${Y}${_.reset}`),zX(Y),console.log(`${_.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${_.reset}`),console.log(),console.log(`${_.bold}详细操作步骤:${_.reset}`),console.log(),console.log(` ${_.bold}① 创建应用${_.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${_.dim}Lodestar${_.reset}), logo 随意。`),console.log(),console.log(` ${_.bold}② 添加机器人能力${_.reset}`),console.log(` 左侧菜单 "${_.cyan}添加应用能力${_.reset}" → 找到 "机器人" → 点 "${_.bold}添加${_.reset}" 按钮。`),console.log(),console.log(` ${_.bold}③ 申请权限 (左侧 "${_.cyan}权限管理${_.reset}" → "${_.bold}开通权限${_.reset}")${_.reset}`),console.log(` ${_.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${_.reset}`),console.log(` ${_.dim}消息类:${_.reset}`),console.log(` • ${_.bold}im:message:send_as_bot${_.reset} ${_.dim}# 以机器人身份发消息${_.reset}`),console.log(` • ${_.bold}im:message${_.reset} ${_.dim}# 接收/操作消息 (核心)${_.reset}`),console.log(` • ${_.bold}im:chat${_.reset} ${_.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${_.reset}`),console.log(` • ${_.bold}im:chat:create${_.reset} ${_.dim}# wt: 自动创建 worktree 群${_.reset}`),console.log(` • ${_.bold}im:chat:delete${_.reset} ${_.dim}# wt: 解散 worktree 群${_.reset}`),console.log(` • ${_.bold}im:chat.members:read${_.reset} ${_.dim}# wt: 判断发起人是否已在群内${_.reset}`),console.log(` • ${_.bold}im:chat.members:write_only${_.reset} ${_.dim}# wt: 把发起人拉进已有 worktree 群${_.reset}`),console.log(` • ${_.bold}im:resource${_.reset} ${_.dim}# 上传/下载附件 (图文双向)${_.reset}`),console.log(` • ${_.bold}im:message.urgent${_.reset} ${_.dim}# 加急推送 (锁屏通知 / Ask)${_.reset}`),console.log(` • ${_.bold}im:message.group_msg${_.reset} ${_.dim}# 敏感: 接收群里所有消息${_.reset}`),console.log(` ${_.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${_.reset}`),console.log(` ${_.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${_.reset}`),console.log(` • ${_.bold}im:message.group_at_msg:readonly${_.reset} ${_.dim}# 读 @ 机器人消息 (兜底)${_.reset}`),console.log(` ${_.dim}卡片类 (Card Kit):${_.reset}`),console.log(` • ${_.bold}cardkit:card:read${_.reset} ${_.dim}# 读卡片状态${_.reset}`),console.log(` • ${_.bold}cardkit:card:write${_.reset} ${_.dim}# 创建/更新卡片 (流式渲染核心)${_.reset}`),console.log(),console.log(` ${_.bold}④ 订阅事件 (左侧 "${_.cyan}事件与回调${_.reset}", 拆两个子页:)${_.reset}`),console.log(` ${_.dim}a)${_.reset} ${_.bold}事件配置${_.reset} 页:`),console.log(` ${_.yellow}• "订阅方式" → 选 "长连接" → 点保存${_.reset}`),console.log(` • 添加事件: ${_.bold}im.message.receive_v1${_.reset} ${_.dim}# 收群消息${_.reset}`),console.log(` ${_.dim}b)${_.reset} ${_.bold}回调配置${_.reset} 页:`),console.log(` ${_.yellow}• "订阅方式" → 选 "长连接" → 点保存${_.reset}`),console.log(` • 添加事件: ${_.bold}card.action.trigger${_.reset} ${_.dim}# 卡片按钮点击回调${_.reset}`),console.log(),console.log(` ${_.bold}⑤ 发布版本${_.reset}`),console.log(` 页面顶部 "${_.bold}创建版本${_.reset}" → 滚到底点 "${_.bold}保存${_.reset}" → 弹框点 "${_.bold}发布${_.reset}"。`),console.log(` ${_.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${_.reset}`),console.log(),console.log(` ${_.bold}⑥ 拿凭据${_.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${_.bold}App ID${_.reset} (${_.dim}cli_...${_.reset}) 和 ${_.bold}App Secret${_.reset}, 待会粘到下面。`),console.log(),console.log(` ${_.bold}⑦ 把机器人拉进群${_.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${_.yellow}群名要等于 projects_root 下的项目目录名${_.reset} (下一步设, 默认是用户主目录)。`),console.log();let Q="",W="";while(!0){Q=await b0("App ID (以 cli_ 开头)",{required:!0}),W=await b0("App Secret",{required:!0}),console.log(`${_.dim}测试中... (调 tenant_access_token endpoint)${_.reset}`);let B=await GX(Q,W);if(B.ok){console.log(`${_.green}✓ Feishu 凭据测试通过${_.reset}`);break}if(console.log(`${_.red}✗ 测试失败:${_.reset} ${B.error}`),console.log(`${_.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${_.reset}`),console.log(),(await b0("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${_.yellow}已取消, 配置未写盘。${_.reset}`),K1.close(),process.exit(1)}$4(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let H=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",X=await b0("projects_root",{default:H});ZZ(Z9,{recursive:!0});let V=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${G9(Q)}"`,`app_secret = "${G9(W)}"`,"","[runtime]",`projects_root = "${G9(X)}"`,""];h$(q$,V.join(`
2
+ var dH=Object.defineProperty;var nH=($)=>$;function aH($,Z){this[$]=nH.bind(null,Z)}var B1=($,Z)=>{for(var J in Z)dH($,J,{get:Z[J],enumerable:!0,configurable:!0,set:aH.bind(Z,J)})};var N=($,Z)=>()=>($&&(Z=$($=0)),Z);import{homedir as oH}from"node:os";import{join as p}from"node:path";function QZ($,Z,J){if($)return $;if(Z)return p(Z,"lodestar");return J}function rH(){if(YZ)return p(process.env.APPDATA??p(Y4,"AppData","Roaming"),"Lodestar");return p(Y4,".config","lodestar")}function tH(){if(YZ)return p(process.env.LOCALAPPDATA??p(Y4,"AppData","Local"),"Lodestar");return p(Y4,".local","share","lodestar")}var Y4,YZ,q6,a,q0,k0,q1,L6,P6,j6,R6,D6,Q4,C$,W4,w$,WZ,HZ,H4,M6,f$,X4;var L0=N(()=>{Y4=oH(),YZ=process.platform==="win32";q6=QZ(process.env.LODESTAR_CONFIG_DIR,process.env.XDG_CONFIG_HOME,rH()),a=QZ(process.env.LODESTAR_DATA_DIR,process.env.XDG_DATA_HOME,tH()),q0=process.env.LODESTAR_CONFIG??p(q6,"config.toml"),k0=p(a,"daemon.pid"),q1=p(a,"daemon.log"),L6=p(a,"session-chat-map.json"),P6=p(a,"session-resume-map.json"),j6=p(a,"session-turns-map.json"),R6=p(a,"session-model-map.json"),D6=p(a,"temp-session-leases.json"),Q4=p(a,"tasklist-map.json"),C$=p(a,"agent-runs"),W4=p(a,"agent-session-ids.json"),w$=p(a,"managed-claude-plugin"),WZ=p(a,"context-window-cache.json"),HZ=p(a,"notify-callbacks.json"),H4=p(a,"alive-on-shutdown.json"),M6=p(a,"inbox"),f$=p(a,"debug.sock"),X4=p(a,"debug-context.json")});import{execSync as XZ}from"node:child_process";import{readFileSync as VZ,writeFileSync as sH}from"node:fs";function eH(){return process.argv[1]??`pid:${process.pid}`}function $X($){try{if(process.platform==="linux")return VZ(`/proc/${$}/cmdline`,"utf8").replace(/\0/g," ").trim();if(process.platform==="darwin")return XZ(`ps -p ${$} -o args=`,{encoding:"utf8",timeout:2000}).trim();if(process.platform==="win32")return XZ(`powershell -NoProfile -Command "(Get-CimInstance Win32_Process -Filter 'ProcessId=${$}').CommandLine"`,{encoding:"utf8",timeout:5000}).trim()||null;return null}catch{return null}}function ZX($,Z){if(!Number.isFinite($)||$<=0||!Z)return!1;let J=$X($);if(!J)return!1;if(process.platform==="win32")return J.toLowerCase().includes(Z.toLowerCase());return J.includes(Z)}function V4($){let Z="";try{Z=VZ($,"utf8")}catch{return{state:"continue"}}let J=Z.split(`
3
+ `),Y=parseInt((J[0]??"").trim(),10),Q=(J[1]??"").trim();if(!Number.isFinite(Y)||Y<=0)return{state:"continue"};if(!Q)try{return process.kill(Y,0),{state:"exit",pid:Y}}catch{return{state:"continue"}}if(ZX(Y,Q))return{state:"exit",pid:Y};return{state:"continue"}}function zZ($){sH($,`${process.pid}
4
+ ${eH()}`)}var F6=()=>{};import{chmodSync as JX,closeSync as U6,fsyncSync as GZ,mkdirSync as YX,openSync as AZ,renameSync as QX,unlinkSync as WX,writeFileSync as HX}from"node:fs";import{randomUUID as XX}from"node:crypto";import{dirname as _Z}from"node:path";function AX($){let Z=_Z($);YX(Z,{recursive:!0,mode:GX})}function KZ($,Z,J){AX($);let Y=`${$}.${process.pid}.${XX()}.tmp`,Q=null;try{Q=AZ(Y,"wx",J),HX(Q,Z),GZ(Q),U6(Q),Q=null,QX(Y,$);try{JX($,J)}catch{}if(process.platform!=="win32"){let W=null;try{W=AZ(_Z($),"r"),GZ(W)}catch{}finally{if(W!==null)try{U6(W)}catch{}}}}catch(W){if(Q!==null)try{U6(Q)}catch{}try{WX(Y)}catch{}throw W}}function g0($,Z){KZ($,Z,VX)}function BZ($,Z){KZ($,Z,zX)}function H0($,Z){g0($,JSON.stringify(Z,null,2)+`
5
+ `)}var VX=384,zX=448,GX=448;var I0=()=>{};var jZ={};B1(jZ,{runSetup:()=>NX});import{execSync as _X,spawn as P1}from"node:child_process";import{existsSync as A4,mkdirSync as PZ,readFileSync as KX}from"node:fs";import{createInterface as BX}from"node:readline/promises";import{delimiter as qX,dirname as LX,join as _4}from"node:path";import{homedir as PX}from"node:os";import{fileURLToPath as jX}from"node:url";async function v$($,Z={}){while(!0){let J=Z.default?`${K.dim} [${Z.default}]${K.reset}`:"",Y=(await L1.question(`${K.cyan}? ${K.reset}${$}${J}
6
+ ${K.green}>${K.reset} `)).trim();if(!Y&&Z.default!==void 0)return Z.default;if(!Y&&Z.required){console.log(`${K.red}必填,请重新输入${K.reset}`);continue}return Y}}function RX($){let Z="═".repeat(58);console.log(`
7
+ ${K.bold}${K.cyan}╔${Z}╗${K.reset}`),console.log(`${K.bold}${K.cyan}║ ${$.padEnd(54)} ║${K.reset}`),console.log(`${K.bold}${K.cyan}╚${Z}╝${K.reset}
8
+ `)}function z4($,Z,J){console.log(`
9
+ ${K.bold}${K.yellow}[${$}/${Z}] ${J}${K.reset}
10
+ `)}function O6($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function G4($){let Z=process.env.PATH??"";if(!Z)return null;let J=process.platform==="win32"?[`${$}.cmd`,`${$}.bat`,`${$}.exe`,$]:[$];for(let Y of Z.split(qX)){if(!Y)continue;for(let Q of J){let W=_4(Y,Q);if(A4(W))return W}}return null}function qZ($){let Z=process.platform==="win32"?"npm.cmd":"npm";return new Promise((J)=>{let Y=P1(Z,["install","-g",`${$}@latest`],{stdio:"inherit",shell:process.platform==="win32"});Y.on("exit",(Q)=>J(Q===0)),Y.on("error",()=>J(!1))})}function LZ($){try{let Z=_X(`"${$}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test(Z)}catch{return!1}}async function DX($){return new Promise((Z)=>{let J=P1($,["login"],{stdio:"inherit",shell:process.platform==="win32"});J.on("exit",(Y)=>Z(Y===0)),J.on("error",()=>Z(!1))})}function MX(){return process.env.CLAUDE_CONFIG_DIR||_4(PX(),".claude")}async function FX($){try{let Z=await fetch("https://open.bigmodel.cn/api/anthropic/v1/models",{headers:{Authorization:`Bearer ${$}`},signal:AbortSignal.timeout(1e4)});if(!Z.ok)return null;let J=await Z.json(),Y=(Array.isArray(J?.data)?J.data:[]).map((_)=>typeof _?.display_name==="string"&&_.display_name?_.display_name:String(_?.id??"")).filter(Boolean);if(!Y.length)return null;let Q=(_)=>{let B=_.match(/(\d+(?:\.\d+)?)/);return B?Number(B[1]):-1},W=(_)=>_.replace(/-Turbo|-Air$/i,""),X=[...Y.filter((_)=>!/-Turbo|-Air/i.test(_))].sort((_,B)=>Q(B)-Q(_)),V=X[0],z=X[X.length-1],G={};if(V)G.ANTHROPIC_DEFAULT_OPUS_MODEL=`${V}[1m]`,G.ANTHROPIC_DEFAULT_SONNET_MODEL=`${V}[1m]`;if(z&&W(z)!==W(V))G.ANTHROPIC_DEFAULT_HAIKU_MODEL=z;return Object.keys(G).length?G:null}catch{return null}}async function UX($){try{let Z=MX();PZ(Z,{recursive:!0});let J=_4(Z,"settings.json"),Y={};if(A4(J)){let X=KX(J,"utf8");try{let V=JSON.parse(X);if(!V||typeof V!=="object"||Array.isArray(V))return{error:`${J} 内容不是 JSON 对象, 拒绝覆盖, 请手动检查`};Y=V}catch{return{error:`${J} 解析失败 (JSON 语法错), 拒绝覆盖, 请手动修复后重跑`}}}let Q=Y.env&&typeof Y.env==="object"&&!Array.isArray(Y.env)?Y.env:{},W={ANTHROPIC_AUTH_TOKEN:$,ANTHROPIC_BASE_URL:"https://open.bigmodel.cn/api/anthropic",API_TIMEOUT_MS:"3000000",CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:"1"},H=await FX($);if(H)Object.assign(W,H);return Y.env={...Q,...W},g0(J,JSON.stringify(Y,null,2)+`
11
+ `),{path:J}}catch(Z){return{error:Z?.message??String(Z)}}}function OX($){try{if(process.platform==="win32")P1(process.env.ComSpec??"cmd.exe",["/c","start",'""',$],{detached:!0,stdio:"ignore",windowsHide:!0}).unref();else if(process.platform==="darwin")P1("open",[$],{detached:!0,stdio:"ignore"}).unref();else P1("xdg-open",[$],{detached:!0,stdio:"ignore"}).unref()}catch{}}async function EX($,Z){try{let Y=await(await fetch("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({app_id:$,app_secret:Z}),signal:AbortSignal.timeout(15000)})).json();if(Y.tenant_access_token)return{ok:!0};return{ok:!1,error:`飞书拒绝: code=${Y.code} msg=${Y.msg??"(no msg)"}`}}catch(J){return{ok:!1,error:`网络错误: ${J?.message??String(J)}`}}}function TX(){try{let $=LX(jX(import.meta.url)),Z=_4($,"lodestar.js");if(!A4(Z))return{error:`找不到 daemon bundle: ${Z}`};let J=P1(process.execPath,[Z],{detached:!0,stdio:"ignore",windowsHide:!0});return J.unref(),{pid:J.pid}}catch($){return{error:$?.message??String($)}}}async function NX(){if(!process.stdin.isTTY)console.error(`${K.red}lodestar-setup: stdin 不是 TTY,无法交互式输入。${K.reset}`),console.error("请直接在 cmd / PowerShell / Terminal 里跑,不要 pipe 或重定向 stdin。"),process.exit(1);if(A4(q0)){if(console.log(`${K.yellow}发现已有配置: ${q0}${K.reset}`),(await v$("覆盖? (y/N)",{default:"n"})).toLowerCase()!=="y"){console.log("已取消"),L1.close();return}}RX("Lodestar 安装向导"),console.log("Lodestar 把 Feishu (飞书) 群聊接到 AI agent。"),console.log("默认后端是 Claude Code; Codex 是可选第二后端, 群里发 model 一键切换。"),console.log("每个群对应一个项目目录, agent 在那里跑、能读写文件。"),console.log(),console.log(`${K.yellow}⚠ Claude 官方限制:${K.reset}`),console.log(` ${K.bold}Claude 订阅 (Pro/Max OAuth 登录) 不支持本项目${K.reset},`),console.log(" 必须走 API 方式 —— 推荐 GLM Coding Plan, 或自备 Anthropic API key。"),console.log(),console.log("本向导依次做 4 件事:"),console.log(` ${K.dim}1) 确保 Claude Code CLI 已装好${K.reset}`),console.log(` ${K.dim}2) GLM Coding Plan API key (推荐, 可选) + Codex (可选)${K.reset}`),console.log(` ${K.dim}3) Feishu 自建应用 (含权限 / 事件 / 发版 + 凭据测试)${K.reset}`),console.log(` ${K.dim}4) 工作目录, 自动启动 daemon${K.reset}`),console.log(),await L1.question(`${K.dim}按 Enter 开始 (Ctrl+C 退出)...${K.reset}`),z4(1,4,"准备 Claude Code CLI");let $=G4("claude");if($)console.log(`${K.green}✓ claude CLI 已就位${K.reset}: ${K.dim}${$}${K.reset}`);else{if(console.log(`${K.yellow}未在 PATH 找到 claude CLI, 自动安装...${K.reset}`),console.log(`${K.dim}运行: npm install -g @anthropic-ai/claude-code@latest${K.reset}`),console.log(),!await qZ("@anthropic-ai/claude-code"))console.error(`
12
+ ${K.red}安装失败。${K.reset}`),console.error("请手动运行后再开向导:"),console.error(` ${K.cyan}npm install -g @anthropic-ai/claude-code@latest${K.reset}`),console.error(` ${K.cyan}lodestar-setup${K.reset}`),L1.close(),process.exit(1);$=G4("claude"),console.log(`${K.green}✓ 安装完成${K.reset}: ${K.dim}${$??"(应该装好了, 但 PATH 找不到 — 重开终端再试)"}${K.reset}`)}console.log(),console.log(`${K.dim}下一步可选配 GLM Coding Plan 自动写入路由; 不配则用本机 Claude Code 现有配置。${K.reset}`),console.log(`${K.dim}记住: 别用 \`claude\` 走订阅 OAuth 登录 —— 订阅不支持本项目, 要用 API key。${K.reset}`),z4(2,4,"GLM Coding Plan (推荐, 可选)"),console.log("GLM Coding Plan 给 Claude Code 接 GLM 系列模型 (支持 1M token 上下文, 中文友好)。"),console.log("订阅后在智谱开放平台拿一个 API key, 粘到下面 —— 向导自动写进 ~/.claude/settings.json。"),console.log(` ${K.dim}拿 key: https://open.bigmodel.cn → 控制台 → API Keys${K.reset}`),console.log(` ${K.dim}不给也行: 以本机 Claude Code 现有配置启动 (确保是 API key 方式, 非订阅)。${K.reset}`),console.log();let Z=await v$("GLM API key (直接回车跳过)",{});if(Z){let B=await UX(Z);if("path"in B)console.log(`${K.green}✓ GLM 路由已写入${K.reset}: ${K.dim}${B.path}${K.reset}`),console.log(`${K.dim}模型 slots 按端点当前列表自动选取(最新一代 opus/sonnet, 1M ctx)${K.reset}`);else console.log(`${K.red}✗ 写入失败:${K.reset} ${B.error}`),console.log(`${K.dim}跳过 GLM 配置, 以本机 Claude Code 现有配置启动。${K.reset}`)}else console.log(`${K.dim}已跳过 GLM, 以本机 Claude Code 现有配置启动。${K.reset}`);if(console.log(),console.log(`${K.bold}Codex (可选第二后端)${K.reset}`),console.log(` ${K.dim}想用 Codex 的话, 登录 ChatGPT 订阅即可, 模型/effort 走 ~/.codex/config.toml, 群里发 model 切换。${K.reset}`),(await v$("现在顺便配置 Codex 后端吗?",{default:"n"})).toLowerCase()==="y"){let B=G4("codex");if(!B){if(console.log(`${K.dim}未找到 codex CLI, 安装 @openai/codex...${K.reset}`),await qZ("@openai/codex"))B=G4("codex")}if(B&&LZ(B))console.log(`${K.green}✓ Codex 已登录 ChatGPT${K.reset}`);else if(B)if(console.log(`${K.dim}启动 \`codex login\`...${K.reset}`),await DX(B)&&LZ(B))console.log(`${K.green}✓ Codex 已登录 ChatGPT${K.reset}`);else console.log(`${K.yellow}Codex 登录未完成 — 不影响默认 Claude 后端; 需要时随时跑 codex login。${K.reset}`);else console.log(`${K.yellow}Codex 安装失败 — 不影响默认 Claude 后端; 需要时手动 npm i -g @openai/codex。${K.reset}`)}else console.log(`${K.dim}已跳过 Codex (需要时随时跑 codex login, 群里发 model 切)。${K.reset}`);z4(3,4,"Feishu 自建应用");let Y="https://open.feishu.cn/app";console.log("打开飞书开放平台 (浏览器):"),console.log(` ${K.cyan}${Y}${K.reset}`),OX(Y),console.log(`${K.dim}(如果浏览器没自动开, 复制上面 URL 粘到浏览器)${K.reset}`),console.log(),console.log(`${K.bold}详细操作步骤:${K.reset}`),console.log(),console.log(` ${K.bold}① 创建应用${K.reset}`),console.log(` 点 "创建企业自建应用", 填名字 (如 ${K.dim}Lodestar${K.reset}), logo 随意。`),console.log(),console.log(` ${K.bold}② 添加机器人能力${K.reset}`),console.log(` 左侧菜单 "${K.cyan}添加应用能力${K.reset}" → 找到 "机器人" → 点 "${K.bold}添加${K.reset}" 按钮。`),console.log(),console.log(` ${K.bold}③ 申请权限 (左侧 "${K.cyan}权限管理${K.reset}" → "${K.bold}开通权限${K.reset}")${K.reset}`),console.log(` ${K.yellow}缺一个都会让 daemon 启动后默默丢消息, 一定要全开。${K.reset}`),console.log(` ${K.dim}消息类:${K.reset}`),console.log(` • ${K.bold}im:message:send_as_bot${K.reset} ${K.dim}# 以机器人身份发消息${K.reset}`),console.log(` • ${K.bold}im:message${K.reset} ${K.dim}# 接收/操作消息 (核心)${K.reset}`),console.log(` • ${K.bold}im:chat${K.reset} ${K.dim}# 读/写群信息 (匹配群名 ↔ 项目目录)${K.reset}`),console.log(` • ${K.bold}im:chat:create${K.reset} ${K.dim}# wt: 自动创建 worktree 群${K.reset}`),console.log(` • ${K.bold}im:chat:delete${K.reset} ${K.dim}# wt: 解散 worktree 群${K.reset}`),console.log(` • ${K.bold}im:chat.members:read${K.reset} ${K.dim}# wt: 判断发起人是否已在群内${K.reset}`),console.log(` • ${K.bold}im:chat.members:write_only${K.reset} ${K.dim}# wt: 把发起人拉进已有 worktree 群${K.reset}`),console.log(` • ${K.bold}im:resource${K.reset} ${K.dim}# 上传/下载附件 (图文双向)${K.reset}`),console.log(` • ${K.bold}im:message.urgent${K.reset} ${K.dim}# 加急推送 (锁屏通知 / Ask)${K.reset}`),console.log(` • ${K.bold}im:message.group_msg${K.reset} ${K.dim}# 敏感: 接收群里所有消息${K.reset}`),console.log(` ${K.dim}└ 关键: 没它机器人只收 @ 自己的消息, 拿不到群里其他对话, 一定要开${K.reset}`),console.log(` ${K.dim}└ 敏感权限要走审批: 申请时填用途, 个人开发者通常秒过${K.reset}`),console.log(` • ${K.bold}im:message.group_at_msg:readonly${K.reset} ${K.dim}# 读 @ 机器人消息 (兜底)${K.reset}`),console.log(` ${K.dim}卡片类 (Card Kit):${K.reset}`),console.log(` • ${K.bold}cardkit:card:read${K.reset} ${K.dim}# 读卡片状态${K.reset}`),console.log(` • ${K.bold}cardkit:card:write${K.reset} ${K.dim}# 创建/更新卡片 (流式渲染核心)${K.reset}`),console.log(),console.log(` ${K.bold}④ 订阅事件 (左侧 "${K.cyan}事件与回调${K.reset}", 拆两个子页:)${K.reset}`),console.log(` ${K.dim}a)${K.reset} ${K.bold}事件配置${K.reset} 页:`),console.log(` ${K.yellow}• "订阅方式" → 选 "长连接" → 点保存${K.reset}`),console.log(` • 添加事件: ${K.bold}im.message.receive_v1${K.reset} ${K.dim}# 收群消息${K.reset}`),console.log(` ${K.dim}b)${K.reset} ${K.bold}回调配置${K.reset} 页:`),console.log(` ${K.yellow}• "订阅方式" → 选 "长连接" → 点保存${K.reset}`),console.log(` • 添加事件: ${K.bold}card.action.trigger${K.reset} ${K.dim}# 卡片按钮点击回调${K.reset}`),console.log(),console.log(` ${K.bold}⑤ 发布版本${K.reset}`),console.log(` 页面顶部 "${K.bold}创建版本${K.reset}" → 滚到底点 "${K.bold}保存${K.reset}" → 弹框点 "${K.bold}发布${K.reset}"。`),console.log(` ${K.yellow}没发版的应用收不到任何事件 — 这步九成新手会忘!${K.reset}`),console.log(),console.log(` ${K.bold}⑥ 拿凭据${K.reset}`),console.log(` 左侧 "凭证与基础信息" → 顶部 ${K.bold}App ID${K.reset} (${K.dim}cli_...${K.reset}) 和 ${K.bold}App Secret${K.reset}, 待会粘到下面。`),console.log(),console.log(` ${K.bold}⑦ 把机器人拉进群${K.reset}`),console.log(" 想用的飞书群 → 群设置 → 群机器人 → 添加机器人 → 选你的应用。"),console.log(` ${K.yellow}群名要等于 projects_root 下的项目目录名${K.reset} (下一步设, 默认是用户主目录)。`),console.log();let Q="",W="";while(!0){Q=await v$("App ID (以 cli_ 开头)",{required:!0}),W=await v$("App Secret",{required:!0}),console.log(`${K.dim}测试中... (调 tenant_access_token endpoint)${K.reset}`);let B=await EX(Q,W);if(B.ok){console.log(`${K.green}✓ Feishu 凭据测试通过${K.reset}`);break}if(console.log(`${K.red}✗ 测试失败:${K.reset} ${B.error}`),console.log(`${K.dim}最常见原因: app_id / app_secret 抄错, 或应用还没 "发布上线" (步骤 ⑤)。${K.reset}`),console.log(),(await v$("重新填? (Y/n)",{default:"y"})).toLowerCase()==="n")console.log(`${K.yellow}已取消, 配置未写盘。${K.reset}`),L1.close(),process.exit(1)}z4(4,4,"工作目录 + 启动"),console.log("每个 Feishu 群对应 projects_root 下同名的目录。"),console.log();let H=process.platform==="win32"?process.env.USERPROFILE??"C:\\Users\\Default":process.env.HOME??"/root",X=await v$("projects_root",{default:H});PZ(q6,{recursive:!0});let V=["# Lodestar config — generated by `lodestar-setup`","# Edit by hand or re-run setup to overwrite.","","[feishu]",`app_id = "${O6(Q)}"`,`app_secret = "${O6(W)}"`,"","[runtime]",`projects_root = "${O6(X)}"`,""];g0(q0,V.join(`
13
13
  `)),console.log(`
14
- ${_.green}${_.bold}✓ 配置已写入${_.reset}`),console.log(` ${_.cyan}${q$}${_.reset}`),console.log(`
15
- ${_.bold}启动 daemon...${_.reset}`);let z=AX(),A=process.platform==="win32"?"\\":"/",K=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(z.pid)console.log(`${_.green}✓ daemon 已在后台启动${_.reset} (pid ${z.pid})`),console.log(),console.log(`${_.bold}最后一步: 在 Feishu 验证${_.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${_.cyan}${X}${A}<群名>${_.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${_.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${_.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${_.cyan}${K}${_.reset}`),console.log(),console.log(`${_.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${_.reset}`);else console.log(`${_.yellow}启动失败: ${z.error}${_.reset}`),console.log(`手动运行: ${_.cyan}lodestar-daemon${_.reset}`);console.log(),K1.close()}var _,K1;var YZ=S(()=>{R$();g$();_={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},K1=eH({input:process.stdin,output:process.stdout})});import{readFileSync as _X}from"node:fs";import{homedir as WZ}from"node:os";function QZ($){return $.replace(/^~(?=\/|$)/,WZ())}function BX($){let Z={_:{}},J="_";for(let Y of $.split(`
16
- `)){let Q=qX(Y).trim();if(!Q)continue;let W=Q.match(/^\[([^\]]+)\]$/);if(W){J=W[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let X=H[2].trim(),V=X.startsWith('"')&&X.endsWith('"'),z=X.startsWith("'")&&X.endsWith("'");if(V||z){if(X=X.slice(1,-1),V)X=X.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=X}}return Z}function qX($){let Z=null,J=!1;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==="double"){if(J){J=!1;continue}if(Q==="\\"){J=!0;continue}if(Q==='"')Z=null;continue}if(Z==="single"){if(Q==="'")Z=null;continue}if(Q==='"')Z="double";else if(Q==="'")Z="single";else if(Q==="#")return $.slice(0,Y)}return $}function HZ(){let $;try{$=_X(q$,"utf8")}catch(U){throw process.stderr.write(`lodestar: cannot read config at ${q$}
14
+ ${K.green}${K.bold}✓ 配置已写入${K.reset}`),console.log(` ${K.cyan}${q0}${K.reset}`),console.log(`
15
+ ${K.bold}启动 daemon...${K.reset}`);let z=TX(),G=process.platform==="win32"?"\\":"/",_=process.platform==="win32"?`${process.env.LOCALAPPDATA??"%LOCALAPPDATA%"}\\Lodestar\\daemon-YYYY-MM-DD.log`:`${process.env.HOME??"~"}/.local/share/lodestar/daemon-YYYY-MM-DD.log`;if(z.pid)console.log(`${K.green}✓ daemon 已在后台启动${K.reset} (pid ${z.pid})`),console.log(),console.log(`${K.bold}最后一步: 在 Feishu 验证${K.reset}`),console.log(" ① 把机器人拉进任意飞书群"),console.log(` ② 群名 = ${K.cyan}${X}${G}<群名>${K.reset} 下的目录名 (新群第一条消息会自动建)`),console.log(" ③ 在群里发任意一条消息, 默认由 Claude 接管"),console.log(` ${K.dim}(群里发 model 可选择已配置账号、动态模型和 effort)${K.reset}`),console.log(),console.log("日志 (按日滚动, 保留近 7 天):"),console.log(` ${K.cyan}${_}${K.reset}`),console.log(),console.log(`${K.dim}若长期跑后台, Linux 配 systemd --user,macOS 配 launchd,Windows 配任务计划程序。${K.reset}`);else console.log(`${K.yellow}启动失败: ${z.error}${K.reset}`),console.log(`手动运行: ${K.cyan}lodestar-daemon${K.reset}`);console.log(),L1.close()}var K,L1;var RZ=N(()=>{L0();I0();K={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",green:"\x1B[32m",yellow:"\x1B[33m",cyan:"\x1B[36m",red:"\x1B[31m"},L1=BX({input:process.stdin,output:process.stdout})});import{readFileSync as kX}from"node:fs";import{homedir as MZ}from"node:os";function DZ($){return $.replace(/^~(?=\/|$)/,MZ())}function SX($){let Z={_:{}},J="_";for(let Y of $.split(`
16
+ `)){let Q=yX(Y).trim();if(!Q)continue;let W=Q.match(/^\[([^\]]+)\]$/);if(W){J=W[1].trim(),Z[J]??={};continue}let H=Q.match(/^([\w.-]+)\s*=\s*(.+)$/);if(H){let X=H[2].trim(),V=X.startsWith('"')&&X.endsWith('"'),z=X.startsWith("'")&&X.endsWith("'");if(V||z){if(X=X.slice(1,-1),V)X=X.replace(/\\([\\"])/g,"$1")}Z[J][H[1]]=X}}return Z}function yX($){let Z=null,J=!1;for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==="double"){if(J){J=!1;continue}if(Q==="\\"){J=!0;continue}if(Q==='"')Z=null;continue}if(Z==="single"){if(Q==="'")Z=null;continue}if(Q==='"')Z="double";else if(Q==="'")Z="single";else if(Q==="#")return $.slice(0,Y)}return $}function FZ(){let $;try{$=kX(q0,"utf8")}catch(O){throw process.stderr.write(`lodestar: cannot read config at ${q0}
17
17
  `+" → 运行 `lodestar-setup` 走交互式向导生成 (Feishu / Codex / 工作目录)\n"+` → 或手写: 设 LODESTAR_CONFIG=/path/to/config.toml 覆盖默认路径
18
18
  `+` [feishu]
19
19
  app_id = "cli_xxx"
20
20
  app_secret = "xxx"
21
21
 
22
- `),U}let Z=BX($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${q$} is missing [feishu].app_id / [feishu].app_secret`);let Q=QZ(Z.runtime?.projects_root??WZ()),W=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(W!=="bucket"&&W!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let H=W,X=Z.notify?.bind??"127.0.0.1",V=Z.notify?.port??"9876";if(!/^\d+$/.test(V.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${V}"`);let z=Number.parseInt(V,10);if(!Number.isFinite(z)||z<=0||z>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${V}"`);let A=(U)=>{let P=Z[U]??{},j={};for(let[O,b]of Object.entries(P))if(typeof b==="string"&&b.length>0)j[O]=b;return j},K=()=>{let U={};for(let[P,j]of Object.entries(Z)){if(!P.startsWith("claude.models."))continue;let b=P.slice(14).trim();if(!b)continue;let x={};for(let[m,h]of Object.entries(j)){if(typeof h!=="string"||h.length===0)continue;if(m.trim()==="model")x.model=h}U[b]=x}return U},B=()=>{let U={},P="projects.";for(let[j,O]of Object.entries(Z)){if(!j.startsWith("projects."))continue;let b=j.slice(9).trim();if(!b)continue;let x={};for(let[m,h]of Object.entries(O)){if(typeof h!=="string"||h.length===0)continue;switch(m.trim()){case"cwd":x.cwd=h;break;case"setting_sources":x.settingSources=h;break;case"strict_mcp":x.strictMcp=h==="true";break;case"tools":x.tools=h;break;case"load_project_mcp":x.loadProjectMcp=h==="true";break}}U[b]=x}return U},q=()=>{let U={},P="token_source.";for(let[j,O]of Object.entries(Z)){if(!j.startsWith("token_source."))continue;let b=j.slice(13).trim();if(!b)continue;let x={};for(let[m,h]of Object.entries(O)){if(typeof h!=="string"||h.length===0)continue;let I=m.trim();if(I==="default")x.default=h==="true";else if(I==="agent"||I==="display"||I==="auth"||I==="base_url"||I==="auth_token"||I==="api_key"||I==="bin"||I==="model"||I==="effort"||I==="models"||I==="slots"||I==="usage")x[I]=h}U[b]=x}return U},L=A("codex.env"),R=A("claude.env"),D=Z.claude?.bin?QZ(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:H},notify:{bind:X,port:z},codex:{env:L},claude:{bin:D,env:R,models:K()},projects:B(),token_sources:q()}}function XZ(){v.token_sources=HZ().token_sources}var v;var U$=S(()=>{R$();v=HZ()});import{appendFileSync as GZ,mkdirSync as RX,readdirSync as LX,unlinkSync as AZ,existsSync as VZ,statSync as PX,renameSync as DX,readFileSync as jX}from"node:fs";import{join as KZ}from"node:path";function _9($="development"){return $!=="test"}function _Z($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function BZ($,Z=d){return KZ(Z,`${A9}${_Z($)}${K9}`)}function FX($){if(!$.startsWith(A9)||!$.endsWith(K9))return null;let Z=$.slice(A9.length,$.length-K9.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Y=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Y.getTime())?null:Y}function qZ($,Z=new Date,J=MX){let Y;try{Y=LX($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),W=0;for(let H of Y){let X=FX(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{AZ(KZ($,H)),W++}catch{}}return W}function UX(){try{if(!VZ(A1))return;let $=PX(A1);if(!$.isFile()||$.size===0)return;let Z=BZ($.mtime);if(VZ(Z)){GZ(Z,jX(A1)),AZ(A1);return}DX(A1,Z)}catch{}}function G($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
23
- `;if(process.stderr.write(J),!_9())return;try{let Y=_Z(Z);if(zZ!==Y)zZ=Y,qZ(d,Z);GZ(BZ(Z),J)}catch{}}var MX=7,A9="daemon-",K9=".log",zZ=null;var g=S(()=>{R$();if(_9())try{RX(d,{recursive:!0})}catch{}if(_9()){UX();try{qZ(d)}catch{}}});function t($){return typeof $==="string"&&$?$:void 0}function c($){return $!=null&&typeof $==="object"?$:null}function e$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function Q4($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Y=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Y}]`}function EX($){let Z=$.slice(0,R9),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function TX($){let Z=c($);if(!Z)return null;let J=c(Z.event),Y=c(Z.payload);return c(Z.item)??c(Z.responseItem)??c(Z.rawItem)??c(J?.item)??c(J?.responseItem)??c(J?.rawItem)??c(Y?.item)??c(Y?.responseItem)??c(Y?.rawItem)??(t1(Z.type)?Z:null)??(J&&t1(J.type)?J:null)??(Y&&t1(Y.type)?Y:null)}function NX($){let Z=[],J=new WeakSet,Y=(Q,W,H)=>{if(Z.length>=R9||H>6)return;if(Array.isArray(Q)){if(W)Z.push(`${W}[]`);if(Q.length>0)Y(Q[0],W?`${W}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let X of Object.keys(Q)){if(Z.length>=R9)return;let V=W?`${W}.${X}`:X;Z.push(V),Y(Q[X],V,H+1)}};return Y($,"",0),Z}function L9($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Y,Q)=>{if(typeof Q==="bigint")return`${Q.toString()}n`;if(typeof Q==="string"&&Q.length>q9)return`${Q.slice(0,q9)}...<truncated ${Q.length-q9} chars>`;if(Q!=null&&typeof Q==="object"){if(Z.has(Q))return"[Circular]";Z.add(Q)}return Q})??String($)}catch(Y){J=`<unserializable: ${Y}>`}if(J.length>B9)return`${J.slice(0,B9)}...<truncated ${J.length-B9} chars>`;return J}function O$($,Z){let J=c(Z),Y=J?c(J.params):null,Q=J?c(J.item)??c(Y?.item):null,W=J?t(J.method)??"-":"-";G([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${e$(W)}`,`rootKeys=${Q4(J)}`,`itemKeys=${Q4(Q)}`,`payload=${L9(Z)}`].join(" "))}function P9($,Z,J){let Y=c(Z),Q=TX(Z),W=[`phase=${e$(J.phase??"event")}`,`method=${e$($)}`,`sourceMethod=${e$(J.sourceMethod)}`,`sourceType=${e$(J.sourceType)}`,`sessionId=${e$(J.sessionId)}`,`threadId=${e$(J.threadId)}`,`turnId=${e$(J.turnId)}`,`itemId=${e$(J.itemId)}`].join(" ");if(G(`codex-process: CONTEXT_COMPACTION_EVENT ${W} rootKeys=${Q4(Y)} itemKeys=${Q4(Q)}`),G(`codex-process: CONTEXT_COMPACTION_PATHS ${W} paths=${EX(NX(Z))}`),Q)G(`codex-process: CONTEXT_COMPACTION_ITEM ${W} item=${L9(Q)}`);G(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${W} payload=${L9(Z)}`)}function t1($){if(typeof $!=="string")return null;return OX.has($)?$:null}function kX($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||RZ.has(Z))return"end";return"event"}function D9($,Z){return LZ($,c(Z)??{})}function j9($){let Z=c($);if(!Z)return null;let J=t(Z.method)??t(Z.type)??"raw_message";return LZ(J,Z)}function LZ($,Z){let J=c(Z.payload),Y=[Z,c(Z.event),J,c(Z.item),c(Z.responseItem),c(Z.rawItem)].filter((V)=>V!=null),Q=null;for(let V of Y)if(Q=t1(V.type),Q)break;if(!RZ.has($)&&!Q)return null;let W=c(Z.item)??c(Z.responseItem)??c(Z.rawItem),H=Q==="compacted"&&J?J:W&&t1(W.type)?W:Z,X=c(H.item)??c(H.responseItem)??c(H.rawItem)??W??{};return{...H,threadId:t(H.threadId)??t(H.thread_id)??t(Z.threadId)??t(Z.thread_id),turnId:t(H.turnId)??t(H.turn_id)??t(Z.turnId)??t(Z.turn_id),itemId:t(H.itemId)??t(H.item_id)??t(X.id)??t(X.itemId)??t(X.item_id),timestamp:t(Z.timestamp)??t(H.timestamp),recordType:t(Z.type),phase:kX(Q,$),sourceMethod:$,sourceType:Q??$}}var RZ,OX,B9=200000,q9=50000,R9=400;var M9=S(()=>{g();RZ=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),OX=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function s1($){return $!=null&&typeof $==="object"?$:null}function $0($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function PZ($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function W4($,Z){return $?$0($[Z]):void 0}function B1($){let Z=s1($);if(!Z)return null;let J=s1(Z.inputTokensDetails)??s1(Z.input_tokens_details),Y=s1(Z.outputTokensDetails)??s1(Z.output_tokens_details),Q={total_tokens:$0(Z.totalTokens??Z.total_tokens),input_tokens:$0(Z.inputTokens??Z.input_tokens),output_tokens:$0(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:$0(Z.reasoningOutputTokens??Z.reasoning_output_tokens??W4(Y,"reasoningTokens")??W4(Y,"reasoning_tokens")),cache_creation_input_tokens:$0(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:$0(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??W4(J,"cachedTokens")??W4(J,"cached_tokens"))};return PZ(Q)?Q:null}function F9($,Z){let J=(Q)=>{let W=$0($?.[Q]),H=$0(Z?.[Q]);if(W===void 0&&H===void 0)return;return Math.max(0,(W??0)-(H??0))},Y={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return PZ(Y)?Y:null}function U9($){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 DZ($){let Z=$.trim();if(Z.length<2)return Z;let J=H4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/''/g,"'");if(Z[0]==='"')return Y.replace(/\\"/g,'"');return Y}function E9($){let Z=yX(String($??"")),J=Z.split(`
22
+ `),O}let Z=SX($),J=Z.feishu?.app_id,Y=Z.feishu?.app_secret;if(!J||!Y)throw Error(`lodestar: ${q0} is missing [feishu].app_id / [feishu].app_secret`);let Q=DZ(Z.runtime?.projects_root??MZ()),W=(Z.runtime?.live_elapsed??"bucket").trim().toLowerCase();if(W!=="bucket"&&W!=="second")throw Error(`lodestar: [runtime].live_elapsed must be "bucket" or "second", got "${Z.runtime?.live_elapsed}"`);let H=W,X=Z.notify?.bind??"127.0.0.1",V=Z.notify?.port??"9876";if(!/^\d+$/.test(V.trim()))throw Error(`lodestar: [notify].port must be an integer, got "${V}"`);let z=Number.parseInt(V,10);if(!Number.isFinite(z)||z<=0||z>65535)throw Error(`lodestar: [notify].port must be 1..65535, got "${V}"`);let G=(O)=>{let j=Z[O]??{},D={};for(let[E,x]of Object.entries(j))if(typeof x==="string"&&x.length>0)D[E]=x;return D},_=()=>{let O={};for(let[j,D]of Object.entries(Z)){if(!j.startsWith("claude.models."))continue;let x=j.slice(14).trim();if(!x)continue;let b={};for(let[u,g]of Object.entries(D)){if(typeof g!=="string"||g.length===0)continue;if(u.trim()==="model")b.model=g}O[x]=b}return O},B=()=>{let O={},j="projects.";for(let[D,E]of Object.entries(Z)){if(!D.startsWith("projects."))continue;let x=D.slice(9).trim();if(!x)continue;let b={};for(let[u,g]of Object.entries(E)){if(typeof g!=="string"||g.length===0)continue;switch(u.trim()){case"cwd":b.cwd=g;break;case"setting_sources":b.settingSources=g;break;case"strict_mcp":b.strictMcp=g==="true";break;case"tools":b.tools=g;break;case"load_project_mcp":b.loadProjectMcp=g==="true";break}}O[x]=b}return O},q=()=>{let O={},j="token_source.";for(let[D,E]of Object.entries(Z)){if(!D.startsWith("token_source."))continue;let x=D.slice(13).trim();if(!x)continue;let b={};for(let[u,g]of Object.entries(E)){if(typeof g!=="string"||g.length===0)continue;let c=u.trim();if(c==="default")b.default=g==="true";else if(c==="agent"||c==="display"||c==="auth"||c==="base_url"||c==="auth_token"||c==="api_key"||c==="bin"||c==="model"||c==="effort"||c==="models"||c==="slots"||c==="usage")b[c]=g}O[x]=b}return O},L=G("codex.env"),P=G("claude.env"),R=Z.claude?.bin?DZ(Z.claude.bin):void 0;return{feishu:{app_id:J,app_secret:Y},runtime:{projects_root:Q,live_elapsed:H},notify:{bind:X,port:z},codex:{env:L},claude:{bin:R,env:P,models:_()},projects:B(),token_sources:q()}}function UZ(){v.token_sources=FZ().token_sources}var v;var U0=N(()=>{L0();v=FZ()});import{appendFileSync as TZ,mkdirSync as xX,readdirSync as bX,unlinkSync as NZ,existsSync as OZ,statSync as CX,renameSync as wX,readFileSync as fX}from"node:fs";import{join as kZ}from"node:path";function N6($="development"){return $!=="test"}function SZ($){let Z=$.getFullYear(),J=String($.getMonth()+1).padStart(2,"0"),Y=String($.getDate()).padStart(2,"0");return`${Z}-${J}-${Y}`}function yZ($,Z=a){return kZ(Z,`${E6}${SZ($)}${T6}`)}function hX($){if(!$.startsWith(E6)||!$.endsWith(T6))return null;let Z=$.slice(E6.length,$.length-T6.length),J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return null;let Y=new Date(Number(J[1]),Number(J[2])-1,Number(J[3]));return Number.isNaN(Y.getTime())?null:Y}function xZ($,Z=new Date,J=vX){let Y;try{Y=bX($)}catch{return 0}let Q=new Date(Z.getFullYear(),Z.getMonth(),Z.getDate()),W=0;for(let H of Y){let X=hX(H);if(!X)continue;if(Math.round((Q.getTime()-X.getTime())/86400000)<J)continue;try{NZ(kZ($,H)),W++}catch{}}return W}function gX(){try{if(!OZ(q1))return;let $=CX(q1);if(!$.isFile()||$.size===0)return;let Z=yZ($.mtime);if(OZ(Z)){TZ(Z,fX(q1)),NZ(q1);return}wX(q1,Z)}catch{}}function A($){let Z=new Date,J=`[${Z.toISOString()}] ${$}
23
+ `;if(process.stderr.write(J),!N6())return;try{let Y=SZ(Z);if(EZ!==Y)EZ=Y,xZ(a,Z);TZ(yZ(Z),J)}catch{}}var vX=7,E6="daemon-",T6=".log",EZ=null;var I=N(()=>{L0();if(N6())try{xX(a,{recursive:!0})}catch{}if(N6()){gX();try{xZ(a)}catch{}}});function e($){return typeof $==="string"&&$?$:void 0}function m($){return $!=null&&typeof $==="object"?$:null}function $$($){if($==null||$==="")return"-";return String($).replace(/\s+/g," ").slice(0,300)}function K4($){if(!$)return"[]";let Z=Object.keys($),J=Z.slice(0,80),Y=Z.length>J.length?`,...+${Z.length-J.length}`:"";return`[${J.join(",")}${Y}]`}function cX($){let Z=$.slice(0,y6),J=$.length>Z.length?`,...+${$.length-Z.length}`:"";return`[${Z.join(",")}${J}]`}function mX($){let Z=m($);if(!Z)return null;let J=m(Z.event),Y=m(Z.payload);return m(Z.item)??m(Z.responseItem)??m(Z.rawItem)??m(J?.item)??m(J?.responseItem)??m(J?.rawItem)??m(Y?.item)??m(Y?.responseItem)??m(Y?.rawItem)??(W2(Z.type)?Z:null)??(J&&W2(J.type)?J:null)??(Y&&W2(Y.type)?Y:null)}function uX($){let Z=[],J=new WeakSet,Y=(Q,W,H)=>{if(Z.length>=y6||H>6)return;if(Array.isArray(Q)){if(W)Z.push(`${W}[]`);if(Q.length>0)Y(Q[0],W?`${W}[]`:"[]",H+1);return}if(Q==null||typeof Q!=="object")return;if(J.has(Q))return;J.add(Q);for(let X of Object.keys(Q)){if(Z.length>=y6)return;let V=W?`${W}.${X}`:X;Z.push(V),Y(Q[X],V,H+1)}};return Y($,"",0),Z}function x6($){let Z=new WeakSet,J;try{J=JSON.stringify($,(Y,Q)=>{if(typeof Q==="bigint")return`${Q.toString()}n`;if(typeof Q==="string"&&Q.length>S6)return`${Q.slice(0,S6)}...<truncated ${Q.length-S6} chars>`;if(Q!=null&&typeof Q==="object"){if(Z.has(Q))return"[Circular]";Z.add(Q)}return Q})??String($)}catch(Y){J=`<unserializable: ${Y}>`}if(J.length>k6)return`${J.slice(0,k6)}...<truncated ${J.length-k6} chars>`;return J}function O0($,Z){let J=m(Z),Y=J?m(J.params):null,Q=J?m(J.item)??m(Y?.item):null,W=J?e(J.method)??"-":"-";A([`codex-process: APP_SERVER_UNHANDLED_${$}`,`method=${$$(W)}`,`rootKeys=${K4(J)}`,`itemKeys=${K4(Q)}`,`payload=${x6(Z)}`].join(" "))}function b6($,Z,J){let Y=m(Z),Q=mX(Z),W=[`phase=${$$(J.phase??"event")}`,`method=${$$($)}`,`sourceMethod=${$$(J.sourceMethod)}`,`sourceType=${$$(J.sourceType)}`,`sessionId=${$$(J.sessionId)}`,`threadId=${$$(J.threadId)}`,`turnId=${$$(J.turnId)}`,`itemId=${$$(J.itemId)}`].join(" ");if(A(`codex-process: CONTEXT_COMPACTION_EVENT ${W} rootKeys=${K4(Y)} itemKeys=${K4(Q)}`),A(`codex-process: CONTEXT_COMPACTION_PATHS ${W} paths=${cX(uX(Z))}`),Q)A(`codex-process: CONTEXT_COMPACTION_ITEM ${W} item=${x6(Q)}`);A(`codex-process: CONTEXT_COMPACTION_PAYLOAD ${W} payload=${x6(Z)}`)}function W2($){if(typeof $!=="string")return null;return IX.has($)?$:null}function pX($,Z){if(Z==="item/started")return"start";if(Z==="item/completed"||Z==="rawResponseItem/completed")return"end";if($==="compacted")return"start";if($==="context_compacted"||bZ.has(Z))return"end";return"event"}function C6($,Z){return CZ($,m(Z)??{})}function w6($){let Z=m($);if(!Z)return null;let J=e(Z.method)??e(Z.type)??"raw_message";return CZ(J,Z)}function CZ($,Z){let J=m(Z.payload),Y=[Z,m(Z.event),J,m(Z.item),m(Z.responseItem),m(Z.rawItem)].filter((V)=>V!=null),Q=null;for(let V of Y)if(Q=W2(V.type),Q)break;if(!bZ.has($)&&!Q)return null;let W=m(Z.item)??m(Z.responseItem)??m(Z.rawItem),H=Q==="compacted"&&J?J:W&&W2(W.type)?W:Z,X=m(H.item)??m(H.responseItem)??m(H.rawItem)??W??{};return{...H,threadId:e(H.threadId)??e(H.thread_id)??e(Z.threadId)??e(Z.thread_id),turnId:e(H.turnId)??e(H.turn_id)??e(Z.turnId)??e(Z.turn_id),itemId:e(H.itemId)??e(H.item_id)??e(X.id)??e(X.itemId)??e(X.item_id),timestamp:e(Z.timestamp)??e(H.timestamp),recordType:e(Z.type),phase:pX(Q,$),sourceMethod:$,sourceType:Q??$}}var bZ,IX,k6=200000,S6=50000,y6=400;var f6=N(()=>{I();bZ=new Set(["thread/compacted","context/compacted","context_compacted","contextCompacted"]),IX=new Set(["compacted","compaction","compaction_trigger","context_compacted","context_compaction","contextCompaction","ContextCompaction"])});function H2($){return $!=null&&typeof $==="object"?$:null}function Z$($){return typeof $==="number"&&Number.isFinite($)?$:void 0}function wZ($){return Object.values($).some((Z)=>typeof Z==="number"&&Number.isFinite(Z))}function B4($,Z){return $?Z$($[Z]):void 0}function j1($){let Z=H2($);if(!Z)return null;let J=H2(Z.inputTokensDetails)??H2(Z.input_tokens_details),Y=H2(Z.outputTokensDetails)??H2(Z.output_tokens_details),Q={total_tokens:Z$(Z.totalTokens??Z.total_tokens),input_tokens:Z$(Z.inputTokens??Z.input_tokens),output_tokens:Z$(Z.outputTokens??Z.output_tokens),reasoning_output_tokens:Z$(Z.reasoningOutputTokens??Z.reasoning_output_tokens??B4(Y,"reasoningTokens")??B4(Y,"reasoning_tokens")),cache_creation_input_tokens:Z$(Z.cacheCreationInputTokens??Z.cache_creation_input_tokens),cache_read_input_tokens:Z$(Z.cachedInputTokens??Z.cached_input_tokens??Z.cacheReadInputTokens??Z.cache_read_input_tokens??B4(J,"cachedTokens")??B4(J,"cached_tokens"))};return wZ(Q)?Q:null}function v6($,Z){let J=(Q)=>{let W=Z$($?.[Q]),H=Z$(Z?.[Q]);if(W===void 0&&H===void 0)return;return Math.max(0,(W??0)-(H??0))},Y={total_tokens:J("total_tokens"),input_tokens:J("input_tokens"),output_tokens:J("output_tokens"),reasoning_output_tokens:J("reasoning_output_tokens"),cache_creation_input_tokens:J("cache_creation_input_tokens"),cache_read_input_tokens:J("cache_read_input_tokens")};return wZ(Y)?Y:null}function h6($){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 fZ($){let Z=$.trim();if(Z.length<2)return Z;let J=q4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/''/g,"'");if(Z[0]==='"')return Y.replace(/\\"/g,'"');return Y}function I6($){let Z=iX(String($??"")),J=Z.split(`
24
24
  `,1)[0]?.trim()??"",Q=(J.startsWith("#")&&!J.startsWith("#!")?J.replace(/^#\s*/,"").trim():"").replace(/^(?:desc|dec|description|说明|目的|用途)\s*[::]\s*/i,"").trim(),W=Q?Z.split(`
25
25
  `).slice(1).join(`
26
- `).trimStart():Z;return{description:Q,command:W||Z}}function q1($,Z=60){let{description:J,command:Y}=E9($);if(J)return J;return SX(Y).replace(/\s+/g," ").trim().slice(0,Z)}function SX($){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 yX($){let Z=$.replace(/\r\n/g,`
27
- `).trim(),J=Z.match(/^(?:\/usr\/bin\/env\s+)?(?:\/[\w./-]+\/)?(?:ba|z|fi)?sh\s+-[A-Za-z]*c[A-Za-z]*\s+([\s\S]+)$/);if(J){let Q=CX(J[1]);return O9(Q||Z)}let Y=xX(Z);if(Y)return Y;return O9(Z)}function xX($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=DZ(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Y=Z[2];for(;;){let Q=Y.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Q)break;let W=Q[1].toLowerCase();if(W==="-command"||W==="-c")return O9(DZ(Q[2]));if(Y=Q[2],W==="-executionpolicy"||W==="-inputformat"||W==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function CX($){let Z=$.trim();if(Z.length<2)return Z;let J=H4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/'\\''/g,"'");return Y.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
28
- `)}function O9($){let Z=$.trim(),J=Z[0];if(!H4[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!bX(Y,J))return Z;if(J!=='"')return Y.replace(/'\s*$/,"");return Y.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
29
- `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(H,X)=>` $(${X})`)}function bX($,Z){let J=H4[Z];for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==='"'&&Q==="\\"&&Y+1<$.length){Y++;continue}if(Q===J)return/^[\s]*$/.test($.slice(Y+1))}return!1}var H4;var X4=S(()=>{H4={'"':'"',"'":"'","“":"”"}});function F($){return $ instanceof Error?$.message:String($)}function V$($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function T9($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,W)=>{Y=setTimeout(()=>W(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as jZ}from"node:path";function fX($){return $.kind==="fresh"?null:$.source.provider}function z$($,Z,J){let Y=fX($);if(Y&&Y!==Z)throw Error(`conversation launch provider mismatch: source=${Y} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!jZ($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!jZ(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")}var R1=()=>{};import{existsSync as wX,readFileSync as vX}from"node:fs";function MZ($,Z){return`${$}:${Z}`}function hX(){if(!wX(r2))return;try{let $=JSON.parse(vX(r2,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");e1=new Set($.ids)}catch($){N9=$ instanceof Error?$:Error(String($))}}function FZ(){if(N9)throw Error(`delegated-agent session registry is unavailable: ${N9.message}`)}function UZ($,Z){FZ();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=MZ($,J);if(e1.has(Y))return;let Q=new Set(e1);Q.add(Y),H$(r2,{version:1,ids:[...Q].sort()}),e1=Q}function V4($,Z){return FZ(),e1.has(MZ($,Z))}var e1,N9=null;var z4=S(()=>{R$();g$();e1=new Set;hX()});import{closeSync as gX,existsSync as K4,mkdirSync as IX,openSync as cX,readdirSync as mX,readSync as uX,statSync as A4,writeFileSync as pX}from"node:fs";import{homedir as f0}from"node:os";import{delimiter as k9,isAbsolute as OZ,join as I$}from"node:path";import{EventEmitter as lX}from"node:events";import{StringDecoder as EZ}from"node:string_decoder";import{spawn as iX}from"cross-spawn";function Z2(){if(process.platform!=="win32"){let $=I$(f0(),".local","npm-global","bin","codex");if(K4($))return $;let Z=I$(f0(),".local","bin","codex");if(K4(Z))return Z}return dX()??"codex"}function dX(){let $=process.env.PATH??"";if(!$)return null;let Z=process.platform==="win32"?["codex.cmd","codex.bat","codex.exe","codex"]:["codex"];for(let J of $.split(k9)){if(!J)continue;for(let Y of Z){let Q=I$(J,Y);if(K4(Q))return Q}}return null}function nX(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([I$(f0(),".local","npm-global","bin"),I$(f0(),".local","bin"),I$(f0(),".bun","bin"),...(process.env.PATH??"").split(k9),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(k9)}function NZ($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function $V($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function ZV($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function k$($){return typeof $==="string"&&JV.includes($)}function YV($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Y of $){let Q=typeof Y==="string"?Y:typeof Y==="object"&&Y?Y.reasoningEffort:null;if(!k$(Q)||Z.has(Q))continue;Z.add(Q);let W=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:W})}return J}function S9($,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:{status:$.status,revisedPrompt:CZ($)}}}return null}function CZ($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function kZ($){if(!$||!K4(TZ))return null;let Z=null,J=[TZ];while(J.length){let Y=J.pop(),Q;try{Q=mX(Y,{withFileTypes:!0})}catch(W){G(`codex-process: cannot scan Codex session dir ${Y}: ${W instanceof Error?W.message:W}`);continue}for(let W of Q){let H=I$(Y,W.name);if(W.isDirectory()){J.push(H);continue}if(!W.isFile())continue;if(!W.name.startsWith("rollout-")||!W.name.endsWith(`${$}.jsonl`))continue;try{let X=A4(H).mtimeMs;if(!Z||X>Z.mtimeMs)Z={path:H,mtimeMs:X}}catch(X){G(`codex-process: cannot stat Codex rollout ${H}: ${X instanceof Error?X.message:X}`)}}}return Z?.path??null}function bZ($,Z,J=aX){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let W=QV($,Z,J);if(W)return W;if(Q.length>2048){let H=fZ($);return G(`codex-process: image generation inline result could not be decoded id=${H} length=${Q.length}`),`Image generation returned ${Q.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Q}if(Q&&typeof Q==="object"){let W=Q.savedPath??Q.saved_path??Q.path;if(typeof W==="string"&&W)return W;return JSON.stringify(Q,null,2)}return""}function QV($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=WV(Y);if(!Q)return null;let W=SZ(Z??"unknown-thread"),H=SZ(fZ($)),X=I$(J,W),V=I$(X,`${H}.${Q.ext}`);try{return IX(X,{recursive:!0}),pX(V,Q.buffer),V}catch(z){return G(`codex-process: failed to write image generation result ${V}: ${z instanceof Error?z.message:z}`),null}}function fZ($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function SZ($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function WV($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=XV(Q[1]),J=Q[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let W=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(W,"base64")}catch{return null}if(H.length<12)return null;let X=HV(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function HV($){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 XV($){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 yZ($,Z,J){let Y=S9($,Z);if(!Y)return null;switch($.type){case"commandExecution":return{...Y,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Y,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Y,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Y,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Y,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Y,output:bZ($,J),isError:$.status==="failed"}}return null}function G4($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return V$(Z)}function xZ($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function VV($,Z,J){let Y=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return q1(Y(Z?.command))||"(空命令)"}case"FileChange":{let Q=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Q>0?`改 ${Q} 个文件`:"文件变更"}case"MCP":return`${Y(Z?.server)}/${Y(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Y(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function wZ($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function zV($){let Z=wZ($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function GV($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let W=Q,H=typeof W?.status==="string"?W.status:"unknown";J.push(`${V$(Y)}: ${H}`)}return J.join(`
30
- `)}var TZ,aX,oX=30000,rX=5000,tX=5000,sX=60000,eX="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",JV,J2="xhigh",$2,L1;var P1=S(()=>{U$();g();M9();X4();R1();z4();M9();TZ=I$(f0(),".codex","sessions"),aX=I$(f0(),".codex","generated_images");JV=["none","minimal","low","medium","high","xhigh","max","ultra"];$2=class $2 extends Error{method;requestId;serverCode;serverMessage;constructor($,Z,J,Y){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Y}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Y;this.name="CodexRpcResponseError"}};L1=class L1 extends lX{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 EZ("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((W)=>{this.resolveExit=W}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=Z2(),J=$V($.allowDelegation!==!1);G(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:nX(),...v.codex.env,...$.hostEnv??{}},Q=$.transformEnv?$.transformEnv(Y):Y;this.proc=iX(Z,J,ZV($.workDir,Q)),this.proc.stdout.on("data",(W)=>this.onStdout(W)),this.proc.stderr.on("data",(W)=>this.onStderr(W)),this.proc.stdin.on("error",(W)=>this.handleStdinError(W)),this.proc.on("exit",(W,H)=>this.handleChildExit(W,H)),this.proc.on("close",(W,H)=>this.handleChildClose(W,H)),this.proc.on("error",(W)=>this.handleChildProcessError(W))}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(G(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){G(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,G(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((W,H)=>Error(`codex app-server closed before ${H.method} response (id=${W})`)),this.serverRequests.clear();let J=$??this.childExitCode,Y=Z??this.childExitSignal,Q=this.conversationMaterializationBarrier();if(Q){Q.then(()=>this.emitProcessExit(J,Y),()=>this.emitProcessExit(J,Y));return}this.emitProcessExit(J,Y)}handleChildProcessError($){G(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Y,Q)=>Error(`codex app-server process failed before ${Q.method} response (id=${Y}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.cancelCapacityRetry(),this.serverRequests.clear(),J=!0;if(this.emit("error",$),J)G(`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(),G(`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(`
31
- `))>=0){let J=this.stdoutBuf.slice(0,Z).trim();if(this.stdoutBuf=this.stdoutBuf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch(Q){G(`codex-process: bad json: ${J.slice(0,200)} (${Q})`);continue}try{this.handleMessage(Y)}catch(Q){G(`codex-process: dispatch error: ${JSON.stringify(Y).slice(0,200)} (${Q})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
26
+ `).trimStart():Z;return{description:Q,command:W||Z}}function R1($,Z=60){let{description:J,command:Y}=I6($);if(J)return J;return lX(Y).replace(/\s+/g," ").trim().slice(0,Z)}function lX($){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 iX($){let Z=$.replace(/\r\n/g,`
27
+ `).trim(),J=Z.match(/^(?:\/usr\/bin\/env\s+)?(?:\/[\w./-]+\/)?(?:ba|z|fi)?sh\s+-[A-Za-z]*c[A-Za-z]*\s+([\s\S]+)$/);if(J){let Q=nX(J[1]);return g6(Q||Z)}let Y=dX(Z);if(Y)return Y;return g6(Z)}function dX($){let Z=$.match(/^("[^"]*"|'[^']*'|“[^”]*”|\S+)\s+([\s\S]*)$/);if(!Z)return null;let J=fZ(Z[1]).replace(/\.exe$/i,"");if(!/(?:^|[\\/])(?:powershell|pwsh)$/i.test(J))return null;let Y=Z[2];for(;;){let Q=Y.match(/^(-[A-Za-z][\w-]*)\s+([\s\S]*)$/);if(!Q)break;let W=Q[1].toLowerCase();if(W==="-command"||W==="-c")return g6(fZ(Q[2]));if(Y=Q[2],W==="-executionpolicy"||W==="-inputformat"||W==="-outputformat")Y=Y.replace(/^(?:"[^"]*"|'[^']*'|\S+)\s+/,"")}return null}function nX($){let Z=$.trim();if(Z.length<2)return Z;let J=q4[Z[0]];if(!J||!Z.endsWith(J))return Z;let Y=Z.slice(1,-1);if(Z[0]==="'")return Y.replace(/'\\''/g,"'");return Y.replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
28
+ `)}function g6($){let Z=$.trim(),J=Z[0];if(!q4[J])return Z;let Y=Z.slice(1);if(!/^#\s*(?:desc|dec|description|说明|目的|用途)\s*[::]/i.test(Y)&&!aX(Y,J))return Z;if(J!=='"')return Y.replace(/'\s*$/,"");return Y.replace(/\s*[”"]\s*$/,"").replace(/\\(["\\$`])/g,"$1").replace(/\\n/g,`
29
+ `).replace(/\s*"\s*'\$\(([^)]*)\)'/g,(H,X)=>` $(${X})`)}function aX($,Z){let J=q4[Z];for(let Y=0;Y<$.length;Y++){let Q=$[Y];if(Z==='"'&&Q==="\\"&&Y+1<$.length){Y++;continue}if(Q===J)return/^[\s]*$/.test($.slice(Y+1))}return!1}var q4;var L4=N(()=>{q4={'"':'"',"'":"'","“":"”"}});function F($){return $ instanceof Error?$.message:String($)}function V0($){return $.length<=16?$:`${$.slice(0,8)}…${$.slice(-4)}`}async function c6($,Z,J){let Y=null;try{return await Promise.race([$,new Promise((Q,W)=>{Y=setTimeout(()=>W(Error(`${J} timed out after ${Z/1000}s`)),Z)})])}finally{if(Y)clearTimeout(Y)}}import{isAbsolute as vZ}from"node:path";function oX($){return $.kind==="fresh"?null:$.source.provider}function z0($,Z,J){let Y=oX($);if(Y&&Y!==Z)throw Error(`conversation launch provider mismatch: source=${Y} target=${Z}`);if($.kind!=="fresh"&&!$.source.sessionId.trim())throw Error("conversation launch source session id is empty");if($.kind!=="fresh"&&$.source.cwd!==null&&(typeof $.source.cwd!=="string"||!vZ($.source.cwd)))throw Error(`conversation launch source cwd is not absolute: ${String($.source.cwd)}`);if($.kind!=="fresh"&&J!==void 0){if(!vZ(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")}var D1=()=>{};import{existsSync as rX,readFileSync as tX}from"node:fs";function hZ($,Z){return`${$}:${Z}`}function sX(){if(!rX(W4))return;try{let $=JSON.parse(tX(W4,"utf8"));if($?.version!==1||!Array.isArray($.ids)||$.ids.some((Z)=>typeof Z!=="string"||!Z))throw Error("invalid delegated-agent session registry");X2=new Set($.ids)}catch($){m6=$ instanceof Error?$:Error(String($))}}function gZ(){if(m6)throw Error(`delegated-agent session registry is unavailable: ${m6.message}`)}function IZ($,Z){gZ();let J=Z.trim();if(!J)throw Error("delegated-agent session id is empty");let Y=hZ($,J);if(X2.has(Y))return;let Q=new Set(X2);Q.add(Y),H0(W4,{version:1,ids:[...Q].sort()}),X2=Q}function P4($,Z){return gZ(),X2.has(hZ($,Z))}var X2,m6=null;var j4=N(()=>{L0();I0();X2=new Set;sX()});import{closeSync as eX,existsSync as M4,mkdirSync as $V,openSync as ZV,readdirSync as JV,readSync as YV,statSync as D4,writeFileSync as QV}from"node:fs";import{homedir as h$}from"node:os";import{delimiter as u6,isAbsolute as cZ,join as c0}from"node:path";import{EventEmitter as WV}from"node:events";import{StringDecoder as mZ}from"node:string_decoder";import{spawn as HV}from"cross-spawn";function z2(){if(process.platform!=="win32"){let $=c0(h$(),".local","npm-global","bin","codex");if(M4($))return $;let Z=c0(h$(),".local","bin","codex");if(M4(Z))return Z}return XV()??"codex"}function XV(){let $=process.env.PATH??"";if(!$)return null;let Z=process.platform==="win32"?["codex.cmd","codex.bat","codex.exe","codex"]:["codex"];for(let J of $.split(u6)){if(!J)continue;for(let Y of Z){let Q=c0(J,Y);if(M4(Q))return Q}}return null}function VV(){if(process.platform==="win32")return process.env.PATH??"";return[...new Set([c0(h$(),".local","npm-global","bin"),c0(h$(),".local","bin"),c0(h$(),".bun","bin"),...(process.env.PATH??"").split(u6),"/usr/local/bin","/usr/bin","/bin"].filter(Boolean))].join(u6)}function pZ($){return typeof $==="string"&&/\bselected\s+model\s+is\s+at\s+capacity\b/i.test($)}function qV($=!0){return["app-server","--listen","stdio://",...$?[]:["--disable","multi_agent"]]}function LV($,Z){return{cwd:$,stdio:["pipe","pipe","pipe"],shell:!1,env:Z}}function S0($){return typeof $==="string"&&PV.includes($)}function jV($){if(!Array.isArray($))return[];let Z=new Set,J=[];for(let Y of $){let Q=typeof Y==="string"?Y:typeof Y==="object"&&Y?Y.reasoningEffort:null;if(!S0(Q)||Z.has(Q))continue;Z.add(Q);let W=typeof Y==="object"&&Y&&typeof Y.description==="string"?Y.description:"";J.push({reasoningEffort:Q,description:W})}return J}function p6($,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:{status:$.status,revisedPrompt:aZ($)}}}return null}function aZ($){let Z=$?.revisedPrompt??$?.revised_prompt;return typeof Z==="string"&&Z?Z:void 0}function lZ($){if(!$||!M4(uZ))return null;let Z=null,J=[uZ];while(J.length){let Y=J.pop(),Q;try{Q=JV(Y,{withFileTypes:!0})}catch(W){A(`codex-process: cannot scan Codex session dir ${Y}: ${W instanceof Error?W.message:W}`);continue}for(let W of Q){let H=c0(Y,W.name);if(W.isDirectory()){J.push(H);continue}if(!W.isFile())continue;if(!W.name.startsWith("rollout-")||!W.name.endsWith(`${$}.jsonl`))continue;try{let X=D4(H).mtimeMs;if(!Z||X>Z.mtimeMs)Z={path:H,mtimeMs:X}}catch(X){A(`codex-process: cannot stat Codex rollout ${H}: ${X instanceof Error?X.message:X}`)}}}return Z?.path??null}function oZ($,Z,J=zV){let Y=$?.savedPath??$?.saved_path;if(typeof Y==="string"&&Y)return Y;let Q=$?.result;if(typeof Q==="string"){let W=RV($,Z,J);if(W)return W;if(Q.length>2048){let H=rZ($);return A(`codex-process: image generation inline result could not be decoded id=${H} length=${Q.length}`),`Image generation returned ${Q.length} chars of inline data, but Lodestar could not materialize it as an image file.`}return Q}if(Q&&typeof Q==="object"){let W=Q.savedPath??Q.saved_path??Q.path;if(typeof W==="string"&&W)return W;return JSON.stringify(Q,null,2)}return""}function RV($,Z,J){let Y=$?.result;if(typeof Y!=="string")return null;let Q=DV(Y);if(!Q)return null;let W=iZ(Z??"unknown-thread"),H=iZ(rZ($)),X=c0(J,W),V=c0(X,`${H}.${Q.ext}`);try{return $V(X,{recursive:!0}),QV(V,Q.buffer),V}catch(z){return A(`codex-process: failed to write image generation result ${V}: ${z instanceof Error?z.message:z}`),null}}function rZ($){let Z=$?.callId??$?.call_id??$?.id;return typeof Z==="string"&&Z?Z:`image-${Date.now()}`}function iZ($){let Z=$.trim().replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^_+|_+$/g,"");return Z?Z.slice(0,140):"unknown"}function DV($){let Z=$.trim(),J=Z,Y=null,Q=Z.match(/^data:image\/([a-zA-Z0-9.+-]+);base64,(.*)$/s);if(Q)Y=FV(Q[1]),J=Q[2];else{if(Z.length<64)return null;if(!/^[a-zA-Z0-9+/=_\-\s]+$/.test(Z))return null}if(J=J.replace(/\s+/g,"").replace(/-/g,"+").replace(/_/g,"/"),!J||J.length%4===1)return null;let W=J.padEnd(Math.ceil(J.length/4)*4,"="),H;try{H=Buffer.from(W,"base64")}catch{return null}if(H.length<12)return null;let X=MV(H)??Y;if(!X)return null;return{buffer:H,ext:X}}function MV($){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 FV($){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 dZ($,Z,J){let Y=p6($,Z);if(!Y)return null;switch($.type){case"commandExecution":return{...Y,output:$.aggregatedOutput??"",isError:$.exitCode!=null&&$.exitCode!==0};case"fileChange":return{...Y,output:JSON.stringify($.changes??[],null,2),isError:$.status==="failed"};case"mcpToolCall":return{...Y,output:$.error?JSON.stringify($.error,null,2):JSON.stringify($.result??null,null,2),isError:!!$.error};case"dynamicToolCall":return{...Y,output:JSON.stringify($.contentItems??[],null,2),isError:$.success===!1};case"webSearch":return{...Y,output:JSON.stringify($.action??{},null,2),isError:!1};case"imageGeneration":return{...Y,output:oZ($,J),isError:$.status==="failed"}}return null}function R4($,Z){if(typeof $==="string"&&$){let J=$.split("/").filter(Boolean).pop();if(J)return J}return V0(Z)}function nZ($){if(typeof $!=="string"||!$)return;if($.startsWith("gAAAA")&&!/[一-鿿]/.test($))return"(继承主线程历史的密文任务书)";return $}function UV($,Z,J){let Y=(Q)=>typeof Q==="string"?Q:"";switch($){case"Bash":{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return R1(Y(Z?.command))||"(空命令)"}case"FileChange":{let Q=Array.isArray(Z?.changes)?Z.changes.length:0;if(J!=null)return"";return Q>0?`改 ${Q} 个文件`:"文件变更"}case"MCP":return`${Y(Z?.server)}/${Y(Z?.tool)}`.slice(0,60);case"WebSearch":return`"${Y(Z?.query).slice(0,50)}"`;default:{if(J!=null){let Q=J.replace(/\s+/g," ").trim();return Q?`→ ${Q.slice(0,60)}`:""}return JSON.stringify(Z??{}).replace(/\s+/g," ").slice(0,60)}}}function tZ($){return(Array.isArray($.receiverThreadIds)?$.receiverThreadIds:[]).filter((J)=>typeof J==="string"&&!!J)}function OV($){let Z=tZ($);return Z.length>0?`派生 ${Z.length} 个子 agent`:"派生子 agent"}function EV($){let Z=$.agentsStates;if(!Z||typeof Z!=="object")return"";let J=[];for(let[Y,Q]of Object.entries(Z)){let W=Q,H=typeof W?.status==="string"?W.status:"unknown";J.push(`${V0(Y)}: ${H}`)}return J.join(`
30
+ `)}var uZ,zV,GV=30000,AV=5000,_V=5000,KV=60000,BV="上一轮因模型暂时满载而中断。请基于当前会话继续完成用户尚未完成的任务,沿用已有进度;执行操作前先确认结果,避免重复已完成的操作。",PV,G2="xhigh",V2,M1;var F1=N(()=>{U0();I();f6();L4();D1();j4();f6();uZ=c0(h$(),".codex","sessions"),zV=c0(h$(),".codex","generated_images");PV=["none","minimal","low","medium","high","xhigh","max","ultra"];V2=class V2 extends Error{method;requestId;serverCode;serverMessage;constructor($,Z,J,Y){super(`codex app-server ${$} failed (id=${Z}, code=${J??"MISS"}): ${Y}`);this.method=$;this.requestId=Z;this.serverCode=J;this.serverMessage=Y;this.name="CodexRpcResponseError"}};M1=class M1 extends WV{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 mZ("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((W)=>{this.resolveExit=W}),this.opts=$,this.tokenSourceId=$.tokenSourceId??null,this.launchKind=($.launch??{kind:"fresh"}).kind;let Z=z2(),J=qV($.allowDelegation!==!1);A(`codex-process: spawn ${Z} app-server (cwd=${$.workDir})`);let Y={...process.env,NPM_CONFIG_LOGLEVEL:"error",PATH:VV(),...v.codex.env,...$.hostEnv??{}},Q=$.transformEnv?$.transformEnv(Y):Y;this.proc=HV(Z,J,LV($.workDir,Q)),this.proc.stdout.on("data",(W)=>this.onStdout(W)),this.proc.stderr.on("data",(W)=>this.onStderr(W)),this.proc.stdin.on("error",(W)=>this.handleStdinError(W)),this.proc.on("exit",(W,H)=>this.handleChildExit(W,H)),this.proc.on("close",(W,H)=>this.handleChildClose(W,H)),this.proc.on("error",(W)=>this.handleChildProcessError(W))}handleStdinError($){let Z=$ instanceof Error?$:Error(String($));if(A(`codex-process: stdin failed: ${Z.message}`),!this.expectedExit)this.emit("error",Z)}handleChildExit($,Z){if(!this.alive){A(`codex-process: duplicate exit ignored code=${$} signal=${Z}`);return}this.alive=!1,this.cancelCapacityRetry(),this.childExitCode=$,this.childExitSignal=Z,A(`codex-process: OS exit code=${$} signal=${Z}; awaiting stdio close`)}handleChildClose($,Z){this.alive=!1,this.cancelCapacityRetry(),this.flushStdoutTail(),this.flushStderrTail(),this.rejectPendingRequests((W,H)=>Error(`codex app-server closed before ${H.method} response (id=${W})`)),this.serverRequests.clear();let J=$??this.childExitCode,Y=Z??this.childExitSignal,Q=this.conversationMaterializationBarrier();if(Q){Q.then(()=>this.emitProcessExit(J,Y),()=>this.emitProcessExit(J,Y));return}this.emitProcessExit(J,Y)}handleChildProcessError($){A(`codex-process: child process error: ${$}`),this.rejectPendingRequests((Y,Q)=>Error(`codex app-server process failed before ${Q.method} response (id=${Y}): ${$.message}`,{cause:$}));let Z=typeof this.proc.pid!=="number",J=!1;if(Z&&this.alive)this.alive=!1,this.cancelCapacityRetry(),this.serverRequests.clear(),J=!0;if(this.emit("error",$),J)A(`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(),A(`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(`
31
+ `))>=0){let J=this.stdoutBuf.slice(0,Z).trim();if(this.stdoutBuf=this.stdoutBuf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch(Q){A(`codex-process: bad json: ${J.slice(0,200)} (${Q})`);continue}try{this.handleMessage(Y)}catch(Q){A(`codex-process: dispatch error: ${JSON.stringify(Y).slice(0,200)} (${Q})`)}}}flushStdoutTail(){if(!this.stdoutBuf)return;this.onStdout(Buffer.from(`
32
32
  `))}onStderr($){this.stderrBuf+=$.toString();let Z;while((Z=this.stderrBuf.indexOf(`
33
- `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())G(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())G(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){G(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Y=typeof $.error?.code==="number"?$.error.code:null,Q=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new $2(J.method,$.id,Y,Q))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=j9($);if(Z){let J=this.withSessionId(Z);P9(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}O$("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=D9($,Z);if(J){let Y=this.withSessionId(J);P9($,Z,Y),this.emit("context_compacted",Y);return}switch($){case"thread/started":{let Y=Z.thread;if(Y?.id)this.sessionId=Y.id;return}case"thread/settings/updated":{let Y=Z.threadSettings;if(typeof Y?.model==="string")this.lastModel=Y.model;if(k$(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=B1(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else G("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=B1(Z.tokenUsage?.total);let Q=Z.tokenUsage?.modelContextWindow;if(typeof Q==="number"&&Q>0)this.lastContextWindow=Q;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){O$("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){O$("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Y=Z.turn??{},Q=typeof Y.id==="string"&&Y.id?Y.id:null;if(Q){if(this.finishedTurnIds?.has(Q)){G(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),G(`codex-process: stale turn/completed ignored turn=${Q} current=${this.currentTurnId}`);return}this.flushRolloutImageGenerations(),this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q)}else O$("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let W=Y.status,H=Y.error??(W==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let X=W==="failed"||!!H,V=W==="completed"&&!X&&!!Q;if(this.lastCompletedTurnId=V?Q:null,this.currentTurnId=null,W==="failed"&&Q&&NZ(H?.message)&&this.scheduleCapacityRetry(H.message,eX))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let z=X?H?.type??H?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Y.durationMs==="number"?Y.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:z,is_error:X},this.emit("result",{subtype:z,is_error:X,...X&&typeof H?.message==="string"?{error:H.message}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Q,checkpoint:V&&this.sessionId?{provider:"codex",kind:"turn",id:Q,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else G("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 O$("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":{G(`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":{G(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{G(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`);let Y=Z.error??Z;if(typeof Z.turnId==="string"&&Z.threadId===this.sessionId&&!this.finishedTurnIds?.has(Z.turnId)&&(!this.currentTurnId||this.currentTurnId===Z.turnId))this.turnError={turnId:Z.turnId,error:Y};this.emit("error",Error(Y.message??Y.summary??"codex app-server error"));return}}O$("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){O$("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=S9(Z,this.opts.workDir);if(!J){O$("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started"))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Y=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Y,J)}return}if(this.feedCollabItem(Z,"completed"))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){O$("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=yZ(Z,this.opts.workDir,this.sessionId??void 0);if(!J){O$("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")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)??V$(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Y=typeof J?.threadId==="string"?J.threadId:"",Q=Z==="started"?S9($,this.opts.workDir):yZ($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let W="output"in Q&&typeof Q.output==="string"?Q.output:void 0;this.emit("subagent_step",{thread_id:Y,item_id:$.id,tool:Q.name,phase:Z,brief:VV(Q.name,Q.input,W)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=G4($.agentPath,J);this.collabAgentNames.set(J,Y),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:J,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(J),Q=G4($.agentPath,J);if(Y!==Q&&!this.collabAgentSettled.has(J))this.collabAgentNames.set(J,Q),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Q})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:J,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let J=$.agentsStates;if(J&&typeof J==="object")for(let[Y,Q]of Object.entries(J))this.translateAgentState(Y,Q,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=wZ($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,G4(null,Q));this.emit("bg_task_settled",{task_id:Q,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:xZ($.prompt),description:zV($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:GV($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Y=Z?.status;if(typeof Y!=="string")return;if(this.collabAgentSettled.has($)){if(Y!=="running"&&Y!=="pendingInit"){if(Y==="errored"||Y==="shutdown"||Y==="notFound"||Y==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Y==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let W=this.collabAgentNames.get($)??G4(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:W}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let H={task_id:$,task_type:"local_agent",description:"子 agent",prompt:xZ(J.prompt)};this.emit("bg_task_started",H);let X={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",X)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let W={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",W);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Q={task_id:$,status:Y==="completed"?"completed":Y==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Q)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new EZ("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=kZ(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=A4($).size,G(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){G(`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??kZ(this.sessionId);if(!$){G(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=A4($).size;if(Q<=this.rolloutReadOffset)return;let W=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(W);let H=cX($,"r"),X=0;try{while(X<W){let V=uX(H,Z,X,W-X,this.rolloutReadOffset+X);if(V===0)break;X+=V}}finally{gX(H)}Z=Z.subarray(0,X),this.rolloutReadOffset+=X}catch(Q){G(`codex-process: image generation rollout read failed ${$}: ${Q instanceof Error?Q.message:Q}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Y=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
34
- `)?"":Y.pop()??"";for(let Q of Y){if(!Q.trim())continue;let W;try{W=JSON.parse(Q)}catch(V){G(`codex-process: image generation rollout JSON parse failed ${$}: ${V instanceof Error?V.message:V}`);continue}let H=W?.payload,X=H?.type;if(X!=="image_generation_end"&&X!=="image_generation_call")continue;this.emitRolloutImageGeneration(H)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=bZ($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&OZ(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:{status:Q,revisedPrompt:CZ($)}}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Y})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Y={questions:(J.questions??[]).map((Q)=>({id:Q.id,header:Q.header,question:Q.question,options:Array.isArray(Q.options)&&Q.options.length?Q.options.map((W)=>({label:W.label,description:W.description})):[{label:"自定义回答",description:Q.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Y}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Y,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:O$("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));return G(`codex-process: stdin write failed: ${Q.message}`),Z?.(Q),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
35
- `,(Y)=>{if(Y)J(Y)}),!0}catch(Y){return J(Y)}}request($,Z,J=oX){let Y=++this.requestCounter;return new Promise((Q,W)=>{let H=setTimeout(()=>{let V=this.pending.get(Y);if(!V)return;this.pending.delete(Y),V.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Y})`))},Math.max(0,J)),X={resolve:Q,reject:W,method:$,timeout:H};this.pending.set(Y,X),this.write({id:Y,method:$,params:Z},(V)=>{if(this.pending.get(Y)!==X)return;this.pending.delete(Y),clearTimeout(H),W(Error(`codex app-server ${$} request write failed (id=${Y}): ${V.message}`,{cause:V}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,result:Z})}respondError($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{G(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Y;if($.kind==="resume")J="thread/resume",Y=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Y=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Y=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Q=Y?.thread;if(typeof Q?.id!=="string"||!Q.id)throw Error(`codex app-server ${J} returned no thread.id`);let W=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(W!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${W??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Q.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Q.id}`);if($.kind==="resume"&&Q.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Q.id}, expected ${$.source.sessionId}`);let H=typeof Q.path==="string"&&Q.path?Q.path:null;if(!H||!OZ(H)||!H.endsWith(`${Q.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${H??"MISS"}`);if(this.sessionId=Q.id,this.conversationRolloutPath=H,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Y?.model)this.lastModel=Y.model;if(k$(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;G(`codex-process: thread=${this.sessionId}`),this.primeRolloutImageGenerationScan(),this.emit("init",{session_id:this.sessionId,thread:Q})}markConversationMaterialized($){if(this.conversationResumable)return;if(!this.sessionId)throw Error(`codex ${$} arrived before thread initialization`);if(this.conversationMaterializationVerification){this.conversationMaterializationRetrySource=$;return}let Z=this.sessionId,J=this.verifyConversationMaterialized($);this.conversationMaterializationVerification=J,J.then(()=>{if(this.sessionId!==Z||this.conversationResumable)return;this.lastConversationMaterializationFailure=null,this.conversationResumable=!0,G(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));this.lastConversationMaterializationFailure=Q,G(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Q.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Q})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Y=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Y)this.markConversationMaterialized(Y)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Q=(await this.request("thread/read",{threadId:Z,includeTurns:!0},rX))?.thread;if(Q?.id!==Z||Q.cwd!==this.opts.workDir||Q.path!==J||!Array.isArray(Q.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=A4(Z)}catch(Y){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Y instanceof Error?Y.message:Y}`,{cause:Y})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(z$($,"codex",this.opts.workDir),$.kind!=="fresh"&&(typeof $.source.sessionId!=="string"||!$.source.sessionId))throw Error(`codex ${$.kind} launch requires a source session id`);if($.kind==="fork"&&$.through){if($.through.provider!=="codex"||$.through.kind!=="turn")throw Error("codex fork through checkpoint must be a codex turn checkpoint");if(typeof $.through.id!=="string"||!$.through.id)throw Error("codex fork through checkpoint requires a turn id")}return $}threadParams(){return{cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandbox:"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.allowDelegation===!1?{"features.multi_agent":!1}:{},...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:this.opts.serviceName??"lodestar"}}sendUserText($,Z=[]){let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).join(" ")+`
33
+ `))>=0){let J=this.stderrBuf.slice(0,Z);if(this.stderrBuf=this.stderrBuf.slice(Z+1),J.trim())A(`codex-process[stderr]: ${J}`)}}flushStderrTail(){let $=this.stderrBuf;if(this.stderrBuf="",$.trim())A(`codex-process[stderr]: ${$}`)}handleMessage($){if(Object.prototype.hasOwnProperty.call($,"id")&&!$.method){let J=this.pending.get($.id);if(!J){A(`codex-process: response for unknown id=${$.id}`);return}if(this.pending.delete($.id),clearTimeout(J.timeout),$.error){let Y=typeof $.error?.code==="number"?$.error.code:null,Q=typeof $.error==="string"?$.error:typeof $.error?.message==="string"?$.error.message:JSON.stringify($.error);J.reject(new V2(J.method,$.id,Y,Q))}else J.resolve($.result);return}if(Object.prototype.hasOwnProperty.call($,"id")&&$.method){this.handleServerRequest($);return}if($.method){this.handleNotification($.method,$.params??{});return}let Z=w6($);if(Z){let J=this.withSessionId(Z);b6(Z.sourceMethod??"raw_message",$,J),this.emit("context_compacted",J);return}O0("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=C6($,Z);if(J){let Y=this.withSessionId(J);b6($,Z,Y),this.emit("context_compacted",Y);return}switch($){case"thread/started":{let Y=Z.thread;if(Y?.id)this.sessionId=Y.id;return}case"thread/settings/updated":{let Y=Z.threadSettings;if(typeof Y?.model==="string")this.lastModel=Y.model;if(S0(Y?.effort))this.lastEffort=Y.effort;return}case"thread/tokenUsage/updated":{let Y=j1(Z.tokenUsage?.last);if(Y)this.lastUsage=Y,this.lastResult.usage=this.lastUsage;else A("codex-process: tokenUsage notification missing last breakdown");this.lastTotalUsage=j1(Z.tokenUsage?.total);let Q=Z.tokenUsage?.modelContextWindow;if(typeof Q==="number"&&Q>0)this.lastContextWindow=Q;this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:Z.threadId,turnId:Z.turnId});return}case"turn/started":{if(typeof Z.threadId!=="string"||Z.threadId!==this.sessionId){O0("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){O0("TURN_COMPLETED_THREAD_MISMATCH",{method:$,params:Z});return}let Y=Z.turn??{},Q=typeof Y.id==="string"&&Y.id?Y.id:null;if(Q){if(this.finishedTurnIds?.has(Q)){A(`codex-process: duplicate turn/completed ignored turn=${Q}`);return}if(this.currentTurnId&&this.currentTurnId!==Q){this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q),A(`codex-process: stale turn/completed ignored turn=${Q} current=${this.currentTurnId}`);return}this.flushRolloutImageGenerations(),this.markConversationMaterialized("turn/completed notification"),this.markTurnStartTerminal(Q),this.rememberFinishedTurn(Q)}else O0("TURN_COMPLETED_MISSING_ID",{method:$,params:Z});let W=Y.status,H=Y.error??(W==="failed"&&this.turnError&&this.turnError.turnId===Q?this.turnError.error:null);this.turnError=null;let X=W==="failed"||!!H,V=W==="completed"&&!X&&!!Q;if(this.lastCompletedTurnId=V?Q:null,this.currentTurnId=null,W==="failed"&&Q&&pZ(H?.message)&&this.scheduleCapacityRetry(H.message,BV))return;this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1;let z=X?H?.type??H?.message??"failed":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof Y.durationMs==="number"?Y.durationMs:null,num_turns:1,usage:this.lastUsage,subtype:z,is_error:X},this.emit("result",{subtype:z,is_error:X,...X&&typeof H?.message==="string"?{error:H.message}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,turn_id:Q,checkpoint:V&&this.sessionId?{provider:"codex",kind:"turn",id:Q,source:{provider:"codex",sessionId:this.sessionId,cwd:this.opts.workDir}}:null});return}case"turn/plan/updated":{this.emit("turn_plan_updated",Z);return}case"item/plan/delta":{this.emit("plan_delta",Z);return}case"thread/goal/updated":{if(Z.goal)this.emit("thread_goal_updated",Z.goal);else A("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 O0("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":{A(`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":{A(`codex-process: ${$}: ${Z.summary??Z.message??JSON.stringify(Z).slice(0,200)}`);return}case"error":{A(`codex-process: server error: ${JSON.stringify(Z).slice(0,500)}`);let Y=Z.error??Z;if(typeof Z.turnId==="string"&&Z.threadId===this.sessionId&&!this.finishedTurnIds?.has(Z.turnId)&&(!this.currentTurnId||this.currentTurnId===Z.turnId))this.turnError={turnId:Z.turnId,error:Y};this.emit("error",Error(Y.message??Y.summary??"codex app-server error"));return}}O0("NOTIFICATION",{method:$,params:Z}),this.emit("raw",{method:$,params:Z})}handleItemStarted($){let Z=$?.item;if(!Z?.id){O0("ITEM_STARTED_MISSING_ID",{method:"item/started",params:$});return}if(this.feedCollabItem(Z,"started"))return;let J=p6(Z,this.opts.workDir);if(!J){O0("ITEM_STARTED_UNMAPPED",{method:"item/started",params:$});return}this.emit("tool_use",{id:Z.id,name:J.name,input:J.input})}handleSubagentItemStarted($){let Z=$?.item;if(!Z?.id)return;if(this.feedCollabItem(Z,"started"))return;this.emitSubagentStep(Z,"started",$)}handleSubagentItemCompleted($){let Z=$?.item;if(!Z?.id)return;if(Z.type==="agentMessage"){let J=typeof Z.text==="string"?Z.text:"";if(J){let Y=typeof $?.threadId==="string"?$.threadId:"";this.collabAgentSummaries.set(Y,J)}return}if(this.feedCollabItem(Z,"completed"))return;this.emitSubagentStep(Z,"completed",$)}handleItemCompleted($){let Z=$?.item;if(!Z?.id){O0("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=dZ(Z,this.opts.workDir,this.sessionId??void 0);if(!J){O0("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")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)??V0(Z)}),this.emit("bg_task_updated",{task_id:Z,patch:{is_backgrounded:!0}});this.emit("bg_task_updated",{task_id:Z,patch:{status:"running"}});return}if(J==="idle"||J==="systemError"){if(!this.collabAgentWasActive.has(Z))return;if(this.collabAgentSettled.has(Z))return;this.collabAgentSettled.add(Z),this.emit("bg_task_settled",{task_id:Z,status:J==="systemError"?"failed":"completed",summary:this.collabAgentSummaries.get(Z)??void 0})}}emitSubagentStep($,Z,J){let Y=typeof J?.threadId==="string"?J.threadId:"",Q=Z==="started"?p6($,this.opts.workDir):dZ($,this.opts.workDir,this.sessionId??void 0);if(!Q)return;let W="output"in Q&&typeof Q.output==="string"?Q.output:void 0;this.emit("subagent_step",{thread_id:Y,item_id:$.id,tool:Q.name,phase:Z,brief:UV(Q.name,Q.input,W)})}feedCollabItem($,Z){if($.type==="subAgentActivity"){let J=typeof $.agentThreadId==="string"?$.agentThreadId:"";if(!J)return!0;if($.kind==="started"&&!this.collabAgentNames.has(J)){let Y=R4($.agentPath,J);this.collabAgentNames.set(J,Y),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Y}),this.emit("bg_task_updated",{task_id:J,patch:{is_backgrounded:!0}})}else if($.kind==="started"){let Y=this.collabAgentNames.get(J),Q=R4($.agentPath,J);if(Y!==Q&&!this.collabAgentSettled.has(J))this.collabAgentNames.set(J,Q),this.emit("bg_task_started",{task_id:J,task_type:"local_agent",description:Q})}else if($.kind==="interrupted")this.emit("bg_task_updated",{task_id:J,patch:{status:"paused"}});return!0}if($.type==="collabAgentToolCall"){let J=$.agentsStates;if(J&&typeof J==="object")for(let[Y,Q]of Object.entries(J))this.translateAgentState(Y,Q,$);if($.tool==="closeAgent"&&Z==="completed"&&$.status!=="failed"){let Y=tZ($);for(let Q of Y){if(this.collabAgentSettled.has(Q))continue;if(this.collabAgentSettled.add(Q),!this.collabAgentNames.has(Q))this.collabAgentNames.set(Q,R4(null,Q));this.emit("bg_task_settled",{task_id:Q,status:"stopped"})}}if($.tool==="spawnAgent"){if(Z==="started")this.emit("tool_use",{id:$.id,name:"Agent",input:{tool:"spawnAgent",prompt:nZ($.prompt),description:OV($),model:typeof $.model==="string"?$.model:void 0}});else if($.status!=="inProgress")this.emit("tool_result",{tool_use_id:$.id,content:EV($),is_error:$.status==="failed"})}return!0}return!1}translateAgentState($,Z,J){let Y=Z?.status;if(typeof Y!=="string")return;if(this.collabAgentSettled.has($)){if(Y!=="running"&&Y!=="pendingInit"){if(Y==="errored"||Y==="shutdown"||Y==="notFound"||Y==="interrupted")this.emit("bg_task_updated",{task_id:$,patch:{status:Y==="errored"?"failed":"killed",error:typeof Z?.message==="string"&&Z.message?Z.message:void 0}});return}this.collabAgentSettled.delete($);let W=this.collabAgentNames.get($)??R4(null,$);this.emit("bg_task_started",{task_id:$,task_type:"local_agent",description:W}),this.emit("bg_task_updated",{task_id:$,patch:{is_backgrounded:!0}})}if(!this.collabAgentNames.has($)){this.collabAgentNames.set($,"子 agent");let H={task_id:$,task_type:"local_agent",description:"子 agent",prompt:nZ(J.prompt)};this.emit("bg_task_started",H);let X={task_id:$,patch:{is_backgrounded:!0}};this.emit("bg_task_updated",X)}if(Y==="running"||Y==="pendingInit"||Y==="interrupted"){let W={task_id:$,patch:{status:Y==="pendingInit"?"pending":Y==="interrupted"?"paused":"running"}};this.emit("bg_task_updated",W);return}if(this.collabAgentSettled.size>=5000)this.collabAgentSettled.clear();this.collabAgentSettled.add($);let Q={task_id:$,status:Y==="completed"?"completed":Y==="errored"?"failed":"stopped",summary:typeof Z?.message==="string"&&Z.message?Z.message:void 0};this.emit("bg_task_settled",Q)}primeRolloutImageGenerationScan(){if(this.rolloutFilePath=null,this.rolloutReadOffset=0,this.rolloutLineRemainder="",this.rolloutDecoder=new mZ("utf8"),this.emittedImageGenerationIds.clear(),!this.sessionId)return;let $=lZ(this.sessionId);if(!$)return;this.rolloutFilePath=$;try{this.rolloutReadOffset=D4($).size,A(`codex-process: image generation rollout scan primed ${$} offset=${this.rolloutReadOffset}`)}catch(Z){A(`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??lZ(this.sessionId);if(!$){A(`codex-process: image generation rollout file not found for thread=${this.sessionId}`);return}this.rolloutFilePath=$;let Z;try{let Q=D4($).size;if(Q<=this.rolloutReadOffset)return;let W=Q-this.rolloutReadOffset;Z=Buffer.allocUnsafe(W);let H=ZV($,"r"),X=0;try{while(X<W){let V=YV(H,Z,X,W-X,this.rolloutReadOffset+X);if(V===0)break;X+=V}}finally{eX(H)}Z=Z.subarray(0,X),this.rolloutReadOffset+=X}catch(Q){A(`codex-process: image generation rollout read failed ${$}: ${Q instanceof Error?Q.message:Q}`);return}let J=this.rolloutLineRemainder+this.rolloutDecoder.write(Z),Y=J.split(/\r?\n/);this.rolloutLineRemainder=J.endsWith(`
34
+ `)?"":Y.pop()??"";for(let Q of Y){if(!Q.trim())continue;let W;try{W=JSON.parse(Q)}catch(V){A(`codex-process: image generation rollout JSON parse failed ${$}: ${V instanceof Error?V.message:V}`);continue}let H=W?.payload,X=H?.type;if(X!=="image_generation_end"&&X!=="image_generation_call")continue;this.emitRolloutImageGeneration(H)}}emitRolloutImageGeneration($){let Z=typeof $?.call_id==="string"?$.call_id:typeof $?.id==="string"?$.id:"";if(!Z||this.emittedImageGenerationIds.has(Z))return;let J=oZ($,this.sessionId??void 0);if(!J)return;let Y=$?.status==="failed",Q=$?.status==="generating"&&cZ(J)?"completed":$?.status;this.emittedImageGenerationIds.add(Z),this.emit("tool_use",{id:Z,name:"ImageGeneration",input:{status:Q,revisedPrompt:aZ($)}}),this.emit("tool_result",{tool_use_id:Z,content:J,is_error:Y})}withSessionId($){let Z=$.sessionId??this.sessionId??void 0;return Z?{...$,sessionId:Z}:$}handleServerRequest($){let Z=String($.id);switch(this.serverRequests.set(Z,{id:$.id,method:$.method,params:$.params}),$.method){case"item/commandExecution/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"Bash",input:{command:J.command,cwd:J.cwd,reason:J.reason},tool_use_id:J.itemId});return}case"item/fileChange/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"FileChange",input:{reason:J.reason,grantRoot:J.grantRoot},tool_use_id:J.itemId});return}case"item/tool/requestUserInput":{let J=$.params??{},Y={questions:(J.questions??[]).map((Q)=>({id:Q.id,header:Q.header,question:Q.question,options:Array.isArray(Q.options)&&Q.options.length?Q.options.map((W)=>({label:W.label,description:W.description})):[{label:"自定义回答",description:Q.isSecret?"请直接在群里回复":"可直接在群里回复"}]}))};this.emit("tool_use",{id:J.itemId,name:"AskUserQuestion",input:Y}),this.emit("can_use_tool",{request_id:Z,tool_name:"AskUserQuestion",input:Y,tool_use_id:J.itemId});return}case"item/permissions/requestApproval":{let J=$.params??{};this.emit("can_use_tool",{request_id:Z,tool_name:"PermissionProfile",input:{cwd:J.cwd,reason:J.reason,permissions:J.permissions},tool_use_id:J.itemId});return}case"item/tool/call":{let J=$.params??{};this.emit("tool_use",{id:J.callId,name:J.namespace?`${J.namespace}.${J.tool}`:J.tool,input:J.arguments}),this.respond(Z,{contentItems:[{type:"inputText",text:"Lodestar does not implement this dynamic tool."}],success:!1});return}case"account/chatgptAuthTokens/refresh":case"attestation/generate":case"applyPatchApproval":case"execCommandApproval":default:O0("SERVER_REQUEST_UNSUPPORTED",$),this.respondError(Z,`unsupported server request: ${$.method}`)}}write($,Z){let J=(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));return A(`codex-process: stdin write failed: ${Q.message}`),Z?.(Q),!1};if(!this.alive)return J(Error(`write to dead process: ${JSON.stringify($).slice(0,200)}`));if(this.proc.stdin.destroyed||this.proc.stdin.writableEnded||!this.proc.stdin.writable)return J(Error("stdin is not writable"));try{return this.proc.stdin.write(JSON.stringify($)+`
35
+ `,(Y)=>{if(Y)J(Y)}),!0}catch(Y){return J(Y)}}request($,Z,J=GV){let Y=++this.requestCounter;return new Promise((Q,W)=>{let H=setTimeout(()=>{let V=this.pending.get(Y);if(!V)return;this.pending.delete(Y),V.reject(Error(`codex app-server ${$} request timed out after ${J}ms (id=${Y})`))},Math.max(0,J)),X={resolve:Q,reject:W,method:$,timeout:H};this.pending.set(Y,X),this.write({id:Y,method:$,params:Z},(V)=>{if(this.pending.get(Y)!==X)return;this.pending.delete(Y),clearTimeout(H),W(Error(`codex app-server ${$} request write failed (id=${Y}): ${V.message}`,{cause:V}))})})}rejectPendingRequests($){for(let[Z,J]of this.pending)clearTimeout(J.timeout),J.reject($(Z,J));this.pending.clear()}respond($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,result:Z})}respondError($,Z){let J=String($),Y=this.serverRequests.get(J);this.serverRequests.delete(J),this.write({id:Y?.id??$,error:{code:-32601,message:Z}})}sendInitialize(){if(!this.readyPromise)this.readyPromise=this.initializeAndStartThread(),this.readyPromise.catch(($)=>{A(`codex-process: initialize failed: ${$}`),this.emit("error",$)})}initializationPromise(){if(!this.readyPromise)this.sendInitialize();return this.readyPromise}isConversationResumable(){return this.conversationResumable}conversationMaterializationBarrier(){return this.conversationMaterializationVerification?this.drainConversationMaterialization():null}conversationMaterializationFailure(){return this.lastConversationMaterializationFailure}async drainConversationMaterialization(){while(this.conversationMaterializationVerification){let $=this.conversationMaterializationVerification;try{await $}catch{}await Promise.resolve()}if(!this.conversationResumable&&this.lastConversationMaterializationFailure)throw this.lastConversationMaterializationFailure}async readRateLimits(){return await this.ensureInitialized(),this.request("account/rateLimits/read",{})}initializeParams(){return{clientInfo:{name:"lodestar",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}}async ensureInitialized(){if(!this.initializePromise)this.initializePromise=this.request("initialize",this.initializeParams()).then(()=>{if(!this.write({method:"initialized"}))throw Error("codex app-server initialized notification write failed")});await this.initializePromise}async initializeAndStartThread(){let $=this.conversationLaunch();await this.ensureInitialized();let Z=this.threadParams(),J,Y;if($.kind==="resume")J="thread/resume",Y=await this.request(J,{threadId:$.source.sessionId,...Z,excludeTurns:!0,persistExtendedHistory:!1});else if($.kind==="fork")J="thread/fork",Y=await this.request(J,{threadId:$.source.sessionId,...$.through?{lastTurnId:$.through.id}:{},...Z,excludeTurns:!0});else J="thread/start",Y=await this.request(J,{...Z,experimentalRawEvents:!1,persistExtendedHistory:!1});let Q=Y?.thread;if(typeof Q?.id!=="string"||!Q.id)throw Error(`codex app-server ${J} returned no thread.id`);let W=typeof Q.cwd==="string"?Q.cwd:typeof Y?.cwd==="string"?Y.cwd:null;if(W!==this.opts.workDir)throw Error(`codex app-server ${J} returned cwd=${W??"MISS"}, expected ${this.opts.workDir}`);if($.kind==="fork"&&Q.id===$.source.sessionId)throw Error(`codex app-server thread/fork returned source thread id ${Q.id}`);if($.kind==="resume"&&Q.id!==$.source.sessionId)throw Error(`codex app-server thread/resume returned thread id ${Q.id}, expected ${$.source.sessionId}`);let H=typeof Q.path==="string"&&Q.path?Q.path:null;if(!H||!cZ(H)||!H.endsWith(`${Q.id}.jsonl`))throw Error(`codex app-server ${J} returned invalid thread.path=${H??"MISS"}`);if(this.sessionId=Q.id,this.conversationRolloutPath=H,this.conversationResumable=!1,$.kind!=="fresh")await this.verifyConversationMaterialized(`${J} response`),this.conversationResumable=!0;if(Y?.model)this.lastModel=Y.model;if(S0(Y?.reasoningEffort))this.lastEffort=Y.reasoningEffort;else this.lastEffort=this.opts.effort??null;A(`codex-process: thread=${this.sessionId}`),this.primeRolloutImageGenerationScan(),this.emit("init",{session_id:this.sessionId,thread:Q})}markConversationMaterialized($){if(this.conversationResumable)return;if(!this.sessionId)throw Error(`codex ${$} arrived before thread initialization`);if(this.conversationMaterializationVerification){this.conversationMaterializationRetrySource=$;return}let Z=this.sessionId,J=this.verifyConversationMaterialized($);this.conversationMaterializationVerification=J,J.then(()=>{if(this.sessionId!==Z||this.conversationResumable)return;this.lastConversationMaterializationFailure=null,this.conversationResumable=!0,A(`codex-process: conversation materialized thread=${Z} source=${$}`),this.emit("conversation_materialized",{session_id:Z,source:$})},(Y)=>{let Q=Y instanceof Error?Y:Error(String(Y));this.lastConversationMaterializationFailure=Q,A(`codex-process: conversation materialization check failed thread=${Z} source=${$}: ${Q.message}`),this.emit("conversation_materialization_failed",{session_id:Z,path:this.conversationRolloutPath,source:$,error:Q})}).finally(()=>{if(this.conversationMaterializationVerification===J)this.conversationMaterializationVerification=null;let Y=this.conversationMaterializationRetrySource;if(this.conversationMaterializationRetrySource=null,!this.conversationResumable&&Y)this.markConversationMaterialized(Y)})}async verifyConversationMaterialized($){let Z=this.sessionId,J=this.conversationRolloutPath;if(!Z||!J)throw Error(`codex ${$} has no initialized rollout identity`);let Q=(await this.request("thread/read",{threadId:Z,includeTurns:!0},AV))?.thread;if(Q?.id!==Z||Q.cwd!==this.opts.workDir||Q.path!==J||!Array.isArray(Q.turns))throw Error(`codex ${$} thread/read returned an invalid materialized thread`);this.assertConversationRolloutMaterialized($)}assertConversationRolloutMaterialized($){let Z=this.conversationRolloutPath;if(!Z)throw Error(`codex ${$} has no authoritative rollout path`);let J;try{J=D4(Z)}catch(Y){throw Error(`codex ${$} rollout is not readable at ${Z}: ${Y instanceof Error?Y.message:Y}`,{cause:Y})}if(!J.isFile())throw Error(`codex ${$} rollout path is not a file: ${Z}`)}conversationLaunch(){let $=this.opts.launch??{kind:"fresh"};if(z0($,"codex",this.opts.workDir),$.kind!=="fresh"&&(typeof $.source.sessionId!=="string"||!$.source.sessionId))throw Error(`codex ${$.kind} launch requires a source session id`);if($.kind==="fork"&&$.through){if($.through.provider!=="codex"||$.through.kind!=="turn")throw Error("codex fork through checkpoint must be a codex turn checkpoint");if(typeof $.through.id!=="string"||!$.through.id)throw Error("codex fork through checkpoint requires a turn id")}return $}threadParams(){return{cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandbox:"danger-full-access",config:{"features.default_mode_request_user_input":!0,...this.opts.allowDelegation===!1?{"features.multi_agent":!1}:{},...this.opts.effort?{model_reasoning_effort:this.opts.effort}:{}},...this.opts.model?{model:this.opts.model}:{},...this.opts.appendSystemPrompt?{developerInstructions:this.opts.appendSystemPrompt}:{},serviceName:this.opts.serviceName??"lodestar"}}sendUserText($,Z=[]){let J=Z.length?Z.map((Q)=>`[file: ${Q}]`).join(" ")+`
36
36
 
37
- `:"";this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.capacityRetryEnabled=!0,this.turnError=null;let Y=this.beginTurnStart(J+$);this.startTurn(J+$,Y).catch((Q)=>this.failTurnStart(Q,Y))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Y of J.data){if(typeof Y?.model!=="string"||!Y.model)continue;$.push({id:typeof Y.id==="string"&&Y.id?Y.id:Y.model,model:Y.model,displayName:typeof Y.displayName==="string"&&Y.displayName?Y.displayName:Y.model,description:typeof Y.description==="string"?Y.description:"",hidden:Y.hidden===!0,isDefault:Y.isDefault===!0,supportedReasoningEfforts:YV(Y.supportedReasoningEfforts),defaultReasoningEffort:k$(Y.defaultReasoningEffort)?Y.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Y=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Y?.data))throw Error("thread/list returned no data array");for(let W of Y.data){if(typeof W?.id!=="string"||!W.id||typeof W.preview!=="string"||typeof W.updatedAt!=="number"||!Number.isFinite(W.updatedAt)||typeof W.cwd!=="string"||W.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof W.status==="string"?W.status:typeof W.status?.type==="string"?W.status.type:void 0;if(V4("codex",W.id))continue;$.push({provider:"codex",sessionId:W.id,cwd:W.cwd,preview:W.preview,ts:W.updatedAt*1000,...H?{status:H}:{}})}let Q=Y?.nextCursor;if(Q!==null&&typeof Q!=="string")throw Error("thread/list returned an invalid nextCursor");if(Q&&Z.has(Q))throw Error(`thread/list repeated pagination cursor ${Q}`);if(Q)Z.add(Q);J=Q}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async setModelSettings($,Z){G("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)){G(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(G(`codex-process: turn/start failed: ${J}`),$ instanceof $2&&$.method==="turn/start"&&NZ($.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})}recordTurnStarted($,Z,J,Y){let Q=typeof $?.id==="string"&&$.id?$.id:null;if(!Q)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Q))return;let W=Y??this.turnStartOwner;if(W?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===W)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let X=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let V={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",V)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Q,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...X?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Y=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Y?.turn,this.sessionId,"turn/start response",J)}catch(Y){if(!this.ownsTurnStartFailure(J)){G(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Y}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>G(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Y=Math.min(tX*2**Math.min(J-1,4),sX),Q=this.turnStartGeneration??0,W={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=W,G(`codex-process: model capacity retry #${J} in ${Y}ms: ${$}`);let H=setTimeout(()=>{if(this.capacityRetryTimer!==H)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Q!==(this.turnStartGeneration??0))return;if(this.turnRetry={...W,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let X=this.beginTurnStart(Z);this.startTurn(Z,X).catch((V)=>this.failTurnStart(V,X))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",W),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){G(`codex-process: permission response for unknown request ${$}`);return}let Q=Z==="allow";switch(Y.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/permissions/requestApproval":if(Q)this.respond($,{permissions:Y.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Q){this.respondError($,J?.denyMessage??"denied by user");return}let W=J?.updatedInput?.answers??{},H={};for(let X of Y.params?.questions??[]){let V=W[X.question]??W[X.id];if(V!==void 0)H[X.id]={answers:[String(V)]}}this.respond($,{answers:H});return}default:O$("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Y.method,params:Y.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,G(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(G(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Y=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw G(`codex-process: kill failed: ${Y.message}`),Y}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function AV($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function y9($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let X=J.exec($);if(!X)break;let V=X[1],z=new RegExp(`^(?: {0,3})${AV(V[0])}{${V.length},}[ \\t]*(?:\\n|$)`,"gm");z.lastIndex=X.index+X[0].length;let A=z.exec($),K=A?A.index+A[0].length:$.length;Z.push({start:X.index,end:K}),Y=K}let Q=[...Z],W=[],H=0;for(let X of Z){if(H<X.start)W.push({start:H,end:X.start});H=X.end}if(H<$.length)W.push({start:H,end:$.length});for(let X of W){let V=$.slice(X.start,X.end),z=/(`+)[^\n]*?\1/g,A;while((A=z.exec(V))!==null)Q.push({start:X.start+A.index,end:X.start+A.index+A[0].length})}return Q.sort((X,V)=>X.start-V.start)}function x9($,Z){if(!$)return $;let J=y9($);if(!J.length)return Z($);let Y="",Q=0;for(let W of J){if(W.start>Q)Y+=Z($.slice(Q,W.start));Y+=$.slice(W.start,W.end),Q=Math.max(Q,W.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function KV($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function vZ($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let W=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${W})`:`\uD83D\uDDBC️ ${W}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function _0($){if(Array.isArray($))return $.map((Y)=>_0(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=_0(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=C9(Z.content);return J}function s($){return x9($,(Z)=>_V(vZ(KV(Z))))}function _V($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
37
+ `:"";this.cancelCapacityRetry(),this.capacityRetryCount=0,this.capacityRetryHasStarted=!1,this.capacityRetryEnabled=!0,this.turnError=null;let Y=this.beginTurnStart(J+$);this.startTurn(J+$,Y).catch((Q)=>this.failTurnStart(Q,Y))}async listModels(){await this.ensureInitialized();let $=[],Z=null;do{let J=await this.request("model/list",{cursor:Z,limit:100,includeHidden:!1});if(!Array.isArray(J?.data))throw Error("model/list returned no data array");for(let Y of J.data){if(typeof Y?.model!=="string"||!Y.model)continue;$.push({id:typeof Y.id==="string"&&Y.id?Y.id:Y.model,model:Y.model,displayName:typeof Y.displayName==="string"&&Y.displayName?Y.displayName:Y.model,description:typeof Y.description==="string"?Y.description:"",hidden:Y.hidden===!0,isDefault:Y.isDefault===!0,supportedReasoningEfforts:jV(Y.supportedReasoningEfforts),defaultReasoningEffort:S0(Y.defaultReasoningEffort)?Y.defaultReasoningEffort:null})}Z=typeof J?.nextCursor==="string"&&J.nextCursor?J.nextCursor:null}while(Z);return $}async listConversations(){await this.ensureInitialized();let $=[],Z=new Set,J=null;do{let Y=await this.request("thread/list",{cursor:J,limit:100,sortKey:"updated_at",sortDirection:"desc",cwd:this.opts.workDir});if(!Array.isArray(Y?.data))throw Error("thread/list returned no data array");for(let W of Y.data){if(typeof W?.id!=="string"||!W.id||typeof W.preview!=="string"||typeof W.updatedAt!=="number"||!Number.isFinite(W.updatedAt)||typeof W.cwd!=="string"||W.cwd!==this.opts.workDir)throw Error("thread/list returned an invalid thread summary");let H=typeof W.status==="string"?W.status:typeof W.status?.type==="string"?W.status.type:void 0;if(P4("codex",W.id))continue;$.push({provider:"codex",sessionId:W.id,cwd:W.cwd,preview:W.preview,ts:W.updatedAt*1000,...H?{status:H}:{}})}let Q=Y?.nextCursor;if(Q!==null&&typeof Q!=="string")throw Error("thread/list returned an invalid nextCursor");if(Q&&Z.has(Q))throw Error(`thread/list repeated pagination cursor ${Q}`);if(Q)Z.add(Q);J=Q}while(J);return $}async readConversationRef($){if(!$.trim())throw Error("thread/read requires a session id");await this.ensureInitialized();let J=(await this.request("thread/read",{threadId:$,includeTurns:!1}))?.thread;if(J?.id!==$||typeof J.cwd!=="string")throw Error("thread/read returned an invalid conversation reference");return{provider:"codex",sessionId:$,cwd:J.cwd}}async setModelSettings($,Z){A("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)){A(`codex-process: ignored stale turn/start failure generation=${Z.generation}`);return}this.turnStartOwner=null,Z.terminal=!0;let J=$ instanceof Error?$.message:String($);if(A(`codex-process: turn/start failed: ${J}`),$ instanceof V2&&$.method==="turn/start"&&pZ($.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})}recordTurnStarted($,Z,J,Y){let Q=typeof $?.id==="string"&&$.id?$.id:null;if(!Q)throw Error(`codex app-server ${J} returned no turn.id`);if(this.finishedTurnIds?.has(Q))return;let W=Y??this.turnStartOwner;if(W?.interrupted){if(this.rememberFinishedTurn(Q),this.turnStartOwner===W)this.turnStartOwner=null;this.interruptTurn(Q);return}this.confirmTurnStart(Q,Y);let H=this.currentTurnId!==Q;if(this.currentTurnId=Q,!H)return;let X=this.capacityRetryHasStarted&&(this.capacityRetryCount??0)>0;if(this.capacityRetryHasStarted=!0,this.capacityRetryTimer&&this.turnRetry){let V={...this.turnRetry,phase:"retrying",delayMs:0};this.cancelCapacityRetry(),this.emit("turn_retry",V)}this.turnRetry=null,this.lastCompletedTurnId=null,this.emit("turn_started",{turn_id:Q,thread_id:typeof Z==="string"&&Z?Z:this.sessionId,...X?{retry:!0}:{}})}beginTurnStart($){let Z={generation:(this.turnStartGeneration??0)+1,turnId:null,confirmed:!1,terminal:!1,inputText:$};return this.turnStartGeneration=Z.generation,this.turnStartOwner=Z,Z}confirmTurnStart($,Z){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let J=Z??this.turnStartOwnersByTurnId.get($)??this.turnStartOwner;if(!J)return;if(J.turnId&&J.turnId!==$)throw Error(`codex turn/start generation=${J.generation} changed turn id from ${J.turnId} to ${$}`);if(J.terminal)return;J.turnId=$,J.confirmed=!0,this.turnStartOwnersByTurnId.set($,J)}markTurnStartTerminal($){if(!this.turnStartOwnersByTurnId)this.turnStartOwnersByTurnId=new Map;let Z=this.turnStartOwnersByTurnId.get($);if(!Z&&this.turnStartOwner&&(!this.currentTurnId||this.currentTurnId===$))Z=this.turnStartOwner,this.confirmTurnStart($,Z);if(!Z)return;if(Z.confirmed=!0,Z.terminal=!0,this.turnStartOwnersByTurnId.delete($),this.turnStartOwner===Z)this.turnStartOwner=null}ownsTurnStartFailure($){return this.turnStartOwner===$&&!$.confirmed&&!$.terminal}rememberFinishedTurn($){if(!this.finishedTurnIds)this.finishedTurnIds=new Set;if(this.finishedTurnIds.add($),this.finishedTurnIds.size<=64)return;let Z=this.finishedTurnIds.values().next().value;if(typeof Z==="string")this.finishedTurnIds.delete(Z)}async startTurn($,Z){let J=Z??this.beginTurnStart($);this.lastCompletedTurnId=null;try{if(!this.readyPromise)this.sendInitialize();if(await this.readyPromise,J.interrupted||this.expectedExit||!this.alive)return;if(!this.sessionId)throw Error("codex thread not initialized");let Y=await this.request("turn/start",{threadId:this.sessionId,input:[{type:"text",text:$,text_elements:[]}],cwd:this.opts.workDir,runtimeWorkspaceRoots:[this.opts.workDir],approvalPolicy:"never",sandboxPolicy:{type:"dangerFullAccess"}});this.recordTurnStarted(Y?.turn,this.sessionId,"turn/start response",J)}catch(Y){if(!this.ownsTurnStartFailure(J)){A(`codex-process: ignored stale turn/start rejection generation=${J.generation}`);return}throw Y}}sendInterrupt(){this.capacityRetryEnabled=!1;let $=!!this.turnRetry&&!this.currentTurnId;this.cancelCapacityRetry();let Z=this.turnStartOwner,J=Z&&!Z.confirmed&&!Z.terminal;if(J)Z.interrupted=!0,Z.terminal=!0;if(this.currentTurnId)this.interruptTurn(this.currentTurnId);else if($||J)this.lastCompletedTurnId=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"interrupted",is_error:!1},this.emit("result",{...this.lastResult,checkpoint:null})}interruptTurn($){if(!this.sessionId)return;this.request("turn/interrupt",{threadId:this.sessionId,turnId:$}).catch((Z)=>A(`codex-process: interrupt failed: ${Z}`))}cancelCapacityRetry(){if(this.capacityRetryTimer)clearTimeout(this.capacityRetryTimer);this.capacityRetryTimer=null,this.turnRetry=null}scheduleCapacityRetry($,Z){if(!this.alive||this.expectedExit||!this.capacityRetryEnabled)return!1;if(this.capacityRetryTimer)return!0;let J=(this.capacityRetryCount??0)+1;this.capacityRetryCount=J;let Y=Math.min(_V*2**Math.min(J-1,4),KV),Q=this.turnStartGeneration??0,W={phase:"waiting",attempt:J,delayMs:Y,message:$};this.turnRetry=W,A(`codex-process: model capacity retry #${J} in ${Y}ms: ${$}`);let H=setTimeout(()=>{if(this.capacityRetryTimer!==H)return;if(this.capacityRetryTimer=null,!this.alive||this.expectedExit||!this.capacityRetryEnabled||this.currentTurnId||Q!==(this.turnStartGeneration??0))return;if(this.turnRetry={...W,phase:"retrying",delayMs:0},this.emit("turn_retry",this.turnRetry),!this.alive||this.expectedExit||!this.capacityRetryEnabled||Q!==(this.turnStartGeneration??0))return;let X=this.beginTurnStart(Z);this.startTurn(Z,X).catch((V)=>this.failTurnStart(V,X))},Y);return this.capacityRetryTimer=H,this.emit("turn_retry",W),!0}sendPermissionResponse($,Z,J){let Y=this.serverRequests.get(String($));if(!Y){A(`codex-process: permission response for unknown request ${$}`);return}let Q=Z==="allow";switch(Y.method){case"item/commandExecution/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/fileChange/requestApproval":this.respond($,{decision:Q?"accept":"decline"});return;case"item/permissions/requestApproval":if(Q)this.respond($,{permissions:Y.params?.permissions??{},scope:"session"});else this.respondError($,J?.denyMessage??"denied by user");return;case"item/tool/requestUserInput":{if(!Q){this.respondError($,J?.denyMessage??"denied by user");return}let W=J?.updatedInput?.answers??{},H={};for(let X of Y.params?.questions??[]){let V=W[X.question]??W[X.id];if(V!==void 0)H[X.id]={answers:[String(V)]}}this.respond($,{answers:H});return}default:O0("APPROVAL_RESPONSE_UNSUPPORTED",{requestId:$,method:Y.method,params:Y.params,decision:Z,payload:J}),this.respondError($,J?.denyMessage??"unsupported approval request")}}sendHookResponse($,Z={}){this.respond($,Z)}isAlive(){return!this.exitEventEmitted}async kill($=5000){if(this.capacityRetryEnabled=!1,this.cancelCapacityRetry(),!this.alive){if(await this.waitForExit($))return;throw Error(`codex app-server exited but stdio did not close within ${$}ms`)}this.expectedExit=!0,A(`codex-process: SIGTERM (timeout=${$}ms)`);let Z=[];if(this.sendSignal("SIGTERM",Z),await this.waitForExit($))return;if(A(`codex-process: SIGKILL (lifecycle not closed after ${$}ms)`),this.alive)this.sendSignal("SIGKILL",Z);if(await this.waitForExit($))return;let J=Z.length?`; ${Z.join("; ")}`:"",Y=Error(`codex app-server did not exit after SIGTERM and SIGKILL (${$}ms each)${J}`);throw A(`codex-process: kill failed: ${Y.message}`),Y}sendSignal($,Z){try{if(!this.proc.kill($)&&this.alive)Z.push(`${$} was not delivered`)}catch(J){Z.push(`${$} failed: ${J instanceof Error?J.message:String(J)}`)}}async waitForExit($){if(this.exitEventEmitted)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!1),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}}});function TV($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function l6($){let Z=[],J=/^(?: {0,3})(`{3,}|~{3,})[^\n]*(?:\n|$)/gm,Y=0;while(Y<$.length){J.lastIndex=Y;let X=J.exec($);if(!X)break;let V=X[1],z=new RegExp(`^(?: {0,3})${TV(V[0])}{${V.length},}[ \\t]*(?:\\n|$)`,"gm");z.lastIndex=X.index+X[0].length;let G=z.exec($),_=G?G.index+G[0].length:$.length;Z.push({start:X.index,end:_}),Y=_}let Q=[...Z],W=[],H=0;for(let X of Z){if(H<X.start)W.push({start:H,end:X.start});H=X.end}if(H<$.length)W.push({start:H,end:$.length});for(let X of W){let V=$.slice(X.start,X.end),z=/(`+)[^\n]*?\1/g,G;while((G=z.exec(V))!==null)Q.push({start:X.start+G.index,end:X.start+G.index+G[0].length})}return Q.sort((X,V)=>X.start-V.start)}function i6($,Z){if(!$)return $;let J=l6($);if(!J.length)return Z($);let Y="",Q=0;for(let W of J){if(W.start>Q)Y+=Z($.slice(Q,W.start));Y+=$.slice(W.start,W.end),Q=Math.max(Q,W.end)}if(Q<$.length)Y+=Z($.slice(Q));return Y}function NV($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function sZ($){return $.replace(/!\[([^\]]*)\]\(([^)]*)\)/g,(J,Y,Q)=>{let W=Q.trim();return Y.trim()?`\uD83D\uDDBC️ ${Y.trim()} (${W})`:`\uD83D\uDDBC️ ${W}`}).replace(/!\[/g,"\uD83D\uDDBC️ [")}function q$($){if(Array.isArray($))return $.map((Y)=>q$(Y));if($==null||typeof $!=="object")return $;let Z=$,J={};for(let[Y,Q]of Object.entries(Z))J[Y]=q$(Q);if(Z.tag==="markdown"&&typeof Z.content==="string")J.content=d6(Z.content);return J}function d($){return i6($,(Z)=>kV(sZ(NV(Z))))}function kV($){return $.replace(/\\\[([\s\S]*?)\\\]/g,(Z,J)=>`
38
38
  \`\`\`
39
39
  ${J.trim()}
40
40
  \`\`\`
@@ -42,170 +42,172 @@ ${J.trim()}
42
42
  \`\`\`
43
43
  ${J.trim()}
44
44
  \`\`\`
45
- `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function C9($){return x9($,vZ)}var M;var S$=S(()=>{M={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_current_model",consoleProjects:"console_projects",consoleHost:"console_host",consoleUsage:"console_usage",modelPanel:"model_panel",tasklistPanel:"tasklist_panel",agentIdentityPanel:"agent_id_panel",agentRunFooter:"agent_run_footer"}});function hZ($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function BV($,Z){let J=$??"";if(J==="subagent"||J==="local_agent")return"subagent";if(J==="shell"||J==="local_bash"||J==="local_shell")return"shell";if(J==="monitor"||J==="local_monitor")return"monitor";if(J==="workflow"||J==="local_workflow")return"workflow";if(Z)return"subagent";return"unknown"}function gZ($){return $==="workflow"||$==="monitor"}function y$($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function w0($){return $.some((Z)=>!y$(Z))}function v9($,Z,J=Date.now()){let Y=BV(Z.task_type,Z.subagent_type),Q=$.active.some((X)=>X.id===Z.task_id),W=$.pending.some((X)=>X.id===Z.task_id);if(Q||W){let X=(V)=>({...V,type:Y,toolUseId:Z.tool_use_id??V.toolUseId,description:Z.description||V.description,subagentType:Z.subagent_type??V.subagentType,workflowName:Z.workflow_name??V.workflowName,prompt:Z.prompt??V.prompt});return{active:Q?$.active.map((V)=>V.id===Z.task_id?X(V):V):$.active,pending:W?$.pending.map((V)=>V.id===Z.task_id?X(V):V):$.pending}}let H={id:Z.task_id,toolUseId:Z.tool_use_id,type:Y,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...gZ(Y)?{isBackgrounded:!0}:{}};return gZ(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function h9($,Z){let J=$.active.some((W)=>W.id===Z.task_id),Y=$.pending.some((W)=>W.id===Z.task_id);if(!J&&!Y)return $;let Q=(W)=>({...W,description:Z.description??W.description,subagentType:Z.subagent_type??W.subagentType,usage:Z.usage??W.usage,lastToolName:Z.last_tool_name??W.lastToolName,summary:Z.summary??W.summary,status:W.status==="pending"?"running":W.status});return{active:J?$.active.map((W)=>W.id===Z.task_id?Q(W):W):$.active,pending:Y?$.pending.map((W)=>W.id===Z.task_id?Q(W):W):$.pending}}function g9($,Z){let J=$.pending.findIndex((H)=>H.id===Z.task_id),Y=Z.patch;if(Y.is_backgrounded===!0&&J>=0){let H=$.pending[J],X={...H,isBackgrounded:!0,status:Y.status??H.status,description:Y.description??H.description,error:Y.error??H.error,endTime:Y.end_time??H.endTime};return{active:[...$.active,X],pending:$.pending.filter((V)=>V.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),W=J>=0;if(Q||W){let H=(X)=>({...X,status:Y.status??X.status,description:Y.description??X.description,error:Y.error??X.error,isBackgrounded:Y.is_backgrounded??X.isBackgrounded,endTime:Y.end_time??X.endTime});return{active:Q?$.active.map((X)=>X.id===Z.task_id?H(X):X):$.active,pending:W?$.pending.map((X)=>X.id===Z.task_id?H(X):X):$.pending}}return $}function I9($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function c9($,Z,J=Date.now()){let Y=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Q)=>Q.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Q)=>Q.id!==Z.task_id)};if($.active.some((Q)=>Q.id===Z.task_id))return{active:$.active.map((Q)=>Q.id===Z.task_id?{...Q,status:Y,usage:Z.usage??Q.usage,summary:Z.summary??Q.summary,endTime:Q.endTime??J}:Q),pending:$.pending};return $}function _4($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>qV){J=Y+1;break}return J===0?$:$.slice(J)}function RV($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return q1(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 LV($,Z){let J=($??"").replace(/\s+/g," ").trim();return Z?`❌ ${J.slice(0,80)}`:J.slice(0,80)}function m9($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((V)=>V.toolUseId===Z),H=$.pending.some((V)=>V.toolUseId===Z);if(!W&&!H)return $;let X=(V)=>V.map((z)=>z.toolUseId===Z?{...z,steps:_4([...z.steps,{toolUseId:J,tool:Y,brief:`${Y} ${RV(Y,Q)}`.trim()}])}:z);return{active:W?X($.active):$.active,pending:H?X($.pending):$.pending}}function u9($,Z,J,Y,Q,W){let H=$.active.some((z)=>z.id===Z),X=$.pending.some((z)=>z.id===Z);if(!H&&!X)return $;let V=(z)=>z.map((A)=>{if(A.id!==Z)return A;if(Q==="started")return{...A,steps:_4([...A.steps,{toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()}])};let K=!1,B=A.steps.map((q)=>{if(K||q.toolUseId!==J)return q;return K=!0,{...q,brief:W?`${q.brief} ${W}`:q.brief}});if(!K&&W)B.push({toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()});return{...A,steps:_4(B)}});return{active:H?V($.active):$.active,pending:X?V($.pending):$.pending}}function p9($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((V)=>V.toolUseId===Z),H=$.pending.some((V)=>V.toolUseId===Z);if(!W&&!H)return $;let X=(V)=>V.map((z)=>{if(z.toolUseId!==Z)return z;let A=!1,K=z.steps.map((B)=>{if(A||B.toolUseId!==J)return B;return A=!0,{...B,brief:`${B.brief} → ${LV(Y,Q)}`}});return{...z,steps:_4(K)}});return{active:W?X($.active):$.active,pending:H?X($.pending):$.pending}}function b9($){if(!$||$<0)return"0s";let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let J=Math.floor(Z/60);if(J<60)return`${J}m${Z%60}s`;return`${Math.floor(J/60)}h${J%60}m`}function mZ($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let W of jV)if(Z<W.limit)return{label:W.label,nextDelayMs:W.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${(Y+1)*10}m+`,nextDelayMs:Q-Z}}function B0($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=f9){let Y=Math.floor((J-f9)/IZ),Q=f9+(Y+1)*IZ;return{label:`${10+Y*5}m+`,nextDelayMs:Q-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:cZ}}return mZ($)}function MV($){return $.subagentType??$.workflowName??DV[$.type]}function w9($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function FV($,Z,J="bucket"){let Y=(Q)=>B0(Q,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Y(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Y(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${b9(w9($))}`;case"failed":return`❌ 失败 ${b9(w9($))}`;case"killed":return`\uD83D\uDC80 已终止 ${b9(w9($))}`}}function uZ($){let Z=$.filter((Y)=>!y$(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function B4($){return`\uD83E\uDDED 后台任务 · ${uZ($)}`}function UV($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(y$($)&&$.summary)Z.push(`\uD83D\uDCDD ${$.summary.slice(0,400)}`,"");for(let J=0;J<$.steps.length;J++)Z.push(`${J+1}. ${$.steps[J].brief}`);return s(Z.length>0?Z.join(`
46
- `):"_(暂无执行记录)_")}function D1($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:Y2.panel($.id),header:{title:{tag:"plain_text",content:`${PV[$.type]} ${MV($)} · ${$.description||"(无描述)"} — ${FV($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:Y2.body($.id),content:UV($)}]}}function l9($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:B4($)}},body:{elements:$.map((Y)=>D1(Y,Z,J))}}}function q4($,Z=Date.now(),J="bucket"){let Y=$.filter(y$);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>D1(Q,Z,J))}}}function i9(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var Y2,qV=1000,PV,DV,jV,cZ=1000,f9=600000,IZ=300000;var d9=S(()=>{S$();X4();Y2={panel:($)=>`bg_${hZ($)}`,body:($)=>`bgb_${hZ($)}`};PV={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},DV={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};jV=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});function n$($){return typeof $==="string"&&OV.includes($)}function j1($){return $?.startsWith("claude:")?"claude":"codex"}function Z0($){return $==="claude"?"Claude":"Codex"}var OV,q0="max",Q2;var v0=S(()=>{OV=["low","medium","high","xhigh","max"];Q2=class Q2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});function R0($){return $.startsWith("claude:")?$:`claude:${$}`}function n9($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(v.claude.models,Z))return v.claude.models[Z]?.model?.trim()||"opus";return Z}var pZ=S(()=>{U$()});import{existsSync as EV,readFileSync as TV}from"node:fs";function a9(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:p5}function H2(){if(W2!==null)return W2;try{W2=EV(a9())?JSON.parse(TV(a9(),"utf8")):{}}catch($){G(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),W2={}}return W2??{}}function kV(){try{H$(a9(),H2())}catch($){G(`context-window-observe: cache write MISS (${$?.message??$})`)}}function o9($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function lZ($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=o9($,Z),Q=H2()[Y];if(Q===J)return;H2()[Y]=J,kV(),G(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function R4($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=H2()[o9($,Z)];return J!=null&&J<NV?Z:`${Z}[1m]`}function L4($,Z){return H2()[o9($,Z)]}var NV=1e6,W2=null;var P4=S(()=>{R$();g();g$()});import{existsSync as j4,readFileSync as eZ}from"node:fs";import{homedir as X2}from"node:os";import{spawn as SV}from"cross-spawn";import{delimiter as iZ,join as h0,posix as yV,win32 as xV}from"node:path";import{EventEmitter as CV}from"node:events";import{query as bV}from"@anthropic-ai/claude-agent-sdk";function fV($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function wV($){return $==="win32"?";":":"}function t9($,...Z){return $==="win32"?xV.join(...Z):yV.join(...Z)}function dZ($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function nZ($){let Z=SV($.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 Z3($={}){let Z=$.platform??process.platform,J=$.exists??j4,Y=$.homeDir??X2();if(Z!=="win32"){let W=[t9(Z,Y,".local","npm-global","bin","claude"),t9(Z,Y,".local","bin","claude")];for(let H of W)if(J(H))return H}let Q=hV($);if(Q)return Q;return null}function J3(){Z3()}function vV($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?v.claude.bin:$.configuredBin;if(J){if(!($.exists??j4)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&dZ(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:nZ,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}let Y=Z3($);if(!Y)return{description:"sdk-default"};if(Z==="win32"&&dZ(Y))return{pathToClaudeCodeExecutable:Y,spawnClaudeCodeProcess:nZ,description:`windows-shell-shim:${Y}`};return{description:"sdk-default"}}function hV($={}){let Z=$.platform??process.platform,J=$.pathEnv??process.env.PATH??"";if(!J)return null;let Y=$.exists??j4,Q=Z==="win32"?["claude.exe","claude.cmd","claude.bat","claude"]:["claude"];for(let W of J.split(wV(Z))){if(!W)continue;for(let H of Q){let X=t9(Z,W,H);if(Y(X))return X}}return null}function aZ(){if(process.platform==="win32")return process.env.PATH??"";let $=[h0(X2(),".local","npm-global","bin"),h0(X2(),".local","bin"),h0(X2(),".bun","bin"),...(process.env.PATH??"").split(iZ),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(iZ)}function gV($){let Z=B1($);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 oZ($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function e9($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||h0(X2(),".claude");return h0(J,"projects",Z)}function $8($,Z){return h0(e9($),`${Z}.jsonl`)}function IV($){let Z;try{Z=eZ($,"utf8")}catch{return null}let J=Z.split(`
47
- `);for(let Y=J.length-1;Y>=0;Y--){let Q=J[Y].trim();if(!Q)continue;try{let W=JSON.parse(Q);if(W?.type==="assistant"&&W?.message?.usage){let H=W.message.usage;if((H.input_tokens??0)+(H.cache_read_input_tokens??0)+(H.cache_creation_input_tokens??0)+(H.output_tokens??0)>0)return H}}catch{}}return null}function tZ($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function cV($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Q of Object.values($)){if(!Q||typeof Q!=="object")continue;let W=Q;Z.input_tokens=(Z.input_tokens??0)+M1(W.inputTokens??W.input_tokens),Z.output_tokens=(Z.output_tokens??0)+M1(W.outputTokens??W.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+M1(W.reasoningOutputTokens??W.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+M1(W.cacheReadInputTokens??W.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+M1(W.cacheCreationInputTokens??W.cache_creation_input_tokens);let H=M1(W.contextWindow??W.context_window);if(H>0)J=Math.max(J??0,H)}let Y=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Y<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Y,{usage:Z,contextWindow:J}}function D4($){return{...$}}function r9($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function mV($,Z){let J=$?{...$}:{},Y=(Q)=>{let W=Z[Q];if(typeof W!=="number"||!Number.isFinite(W))return;J[Q]=(J[Q]??0)+W};return Y("total_tokens"),Y("input_tokens"),Y("output_tokens"),Y("reasoning_output_tokens"),Y("cache_creation_input_tokens"),Y("cache_read_input_tokens"),J}function M1($){return typeof $==="number"&&Number.isFinite($)?$:0}function Y3($){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(`
48
- `);return $==null?"":JSON.stringify($,null,2)}function uV($){let Z=Y3($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Y=J.map((Q)=>{if(typeof Q==="string")return Q;if(Q&&typeof Q==="object"&&typeof Q.text==="string")return Q.text;return JSON.stringify(Q)}).filter(Boolean);if(Y.length>0)return Y.join(`
49
- `)}}catch{}return Z}function pV($){return`server_tool:${$}`}function lV($){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 iV($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function dV($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[q0];return{id:R0($.value),model:R0($.value),displayName:$.displayName||R0($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(q0)?q0:Z[0]}}function aV($){if(!$?.settingSources)return[...sZ];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...sZ]}function oV($){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 rV($){let Z=h0($,".mcp.json"),J;try{J=eZ(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")G(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Y}`);return}try{let Y=JSON.parse(J);if(Y&&typeof Y==="object"&&Y.mcpServers&&typeof Y.mcpServers==="object")return Y.mcpServers;G(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){G(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function tV($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>sV(Y)).filter((Y)=>Y!==null)}function sV($){let Z=$&&typeof $==="object"?$:{question:$},J=s9(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=eV(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Y,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function eV($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Y=J,Q=s9(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let W=s9(Y.description,Y.detail,Y.preview);Z.push(W?{label:Q,description:W}:{label:Q})}return Z}function s9(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var $3,rZ,nV="default",sZ,Z8;var M4=S(()=>{U$();g();v0();pZ();P4();$3=class $3{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($))}};rZ=new Map;sZ=["project","local"];Z8=class Z8 extends CV{provider="claude";tokenSourceId;opts;input=new $3;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;pendingPermissions=new Map;requestCounter=0;cumulativeUsageFromResults=null;turnActive=!1;emittedToolUseIds=new Set;emittedToolResultIds=new Set;pendingServerToolInputs=[];sessionId=null;lastAssistantUuid=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;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?R0($.model):null}sendInitialize(){if(this.started)return;this.started=!0;let $=n9(this.opts.model),Z=this.opts.profile;if(Z)G(`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??aV(Z),Y=fV(J,this.opts.managedSkillPluginPath),Q=oV(Z),W=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?rV(this.opts.workDir):void 0;try{let X=vV();G(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${X.description}`),this.query=bV({prompt:this.input,options:{cwd:this.opts.workDir,abortController:this.abortController,...$?{model:$}:{},effort:this.opts.effort,resume:this.opts.resumeSessionId,...this.opts.resumeSessionAt?{resumeSessionAt:this.opts.resumeSessionAt}:{},...this.opts.forkSession?{forkSession:!0}:{},...X.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:X.pathToClaudeCodeExecutable}:{},...X.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:X.spawnClaudeCodeProcess}:{},permissionMode:nV,env:this.opts.transformEnv?this.opts.transformEnv({...process.env,PATH:aZ(),...v.claude.env,...this.opts.hostEnv??{}}):{...process.env,PATH:aZ(),...v.claude.env,...this.opts.hostEnv??{}},settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...W?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(V,z,A)=>this.canUseTool(V,z,A),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(V)=>{let z=V.trim();if(z)G(`claude-agent-process[stderr]: ${z}`)}}})}catch(X){let V=X instanceof Error?X:Error(String(X));this.emit("error",V),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){G("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
45
+ `).replace(/\\\(([\s\S]*?)\\\)/g,(Z,J)=>`\`${J.trim()}\``).replace(/\$([^$\n]+)\$/g,(Z,J)=>/\\|\^|_|=/.test(J)?`\`${J.trim()}\``:Z)}function d6($){return i6($,sZ)}var M;var y0=N(()=>{M={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_current_model",consoleProjects:"console_projects",consoleHost:"console_host",consoleUsage:"console_usage",modelPanel:"model_panel",tasklistPanel:"tasklist_panel",agentIdentityPanel:"agent_id_panel",agentRunFooter:"agent_run_footer"}});function eZ($){let Z=2166136261;for(let J=0;J<$.length;J++)Z^=$.charCodeAt(J),Z=Math.imul(Z,16777619);return(Z>>>0).toString(36)}function SV($,Z){let J=$??"";if(J==="subagent"||J==="local_agent")return"subagent";if(J==="shell"||J==="local_bash"||J==="local_shell")return"shell";if(J==="monitor"||J==="local_monitor")return"monitor";if(J==="workflow"||J==="local_workflow")return"workflow";if(Z)return"subagent";return"unknown"}function $3($){return $==="workflow"||$==="monitor"}function x0($){return $.status==="completed"||$.status==="failed"||$.status==="killed"}function g$($){return $.some((Z)=>!x0(Z))}function r6($,Z,J=Date.now()){let Y=SV(Z.task_type,Z.subagent_type),Q=$.active.some((X)=>X.id===Z.task_id),W=$.pending.some((X)=>X.id===Z.task_id);if(Q||W){let X=(V)=>({...V,type:Y,toolUseId:Z.tool_use_id??V.toolUseId,description:Z.description||V.description,subagentType:Z.subagent_type??V.subagentType,workflowName:Z.workflow_name??V.workflowName,prompt:Z.prompt??V.prompt});return{active:Q?$.active.map((V)=>V.id===Z.task_id?X(V):V):$.active,pending:W?$.pending.map((V)=>V.id===Z.task_id?X(V):V):$.pending}}let H={id:Z.task_id,toolUseId:Z.tool_use_id,type:Y,description:Z.description,subagentType:Z.subagent_type,workflowName:Z.workflow_name,prompt:Z.prompt,status:"running",startedAt:J,steps:[],...$3(Y)?{isBackgrounded:!0}:{}};return $3(Y)?{active:[...$.active,H],pending:$.pending}:{active:$.active,pending:[...$.pending,H]}}function t6($,Z){let J=$.active.some((W)=>W.id===Z.task_id),Y=$.pending.some((W)=>W.id===Z.task_id);if(!J&&!Y)return $;let Q=(W)=>({...W,description:Z.description??W.description,subagentType:Z.subagent_type??W.subagentType,usage:Z.usage??W.usage,lastToolName:Z.last_tool_name??W.lastToolName,summary:Z.summary??W.summary,status:W.status==="pending"?"running":W.status});return{active:J?$.active.map((W)=>W.id===Z.task_id?Q(W):W):$.active,pending:Y?$.pending.map((W)=>W.id===Z.task_id?Q(W):W):$.pending}}function s6($,Z){let J=$.pending.findIndex((H)=>H.id===Z.task_id),Y=Z.patch;if(Y.is_backgrounded===!0&&J>=0){let H=$.pending[J],X={...H,isBackgrounded:!0,status:Y.status??H.status,description:Y.description??H.description,error:Y.error??H.error,endTime:Y.end_time??H.endTime};return{active:[...$.active,X],pending:$.pending.filter((V)=>V.id!==Z.task_id)}}let Q=$.active.some((H)=>H.id===Z.task_id),W=J>=0;if(Q||W){let H=(X)=>({...X,status:Y.status??X.status,description:Y.description??X.description,error:Y.error??X.error,isBackgrounded:Y.is_backgrounded??X.isBackgrounded,endTime:Y.end_time??X.endTime});return{active:Q?$.active.map((X)=>X.id===Z.task_id?H(X):X):$.active,pending:W?$.pending.map((X)=>X.id===Z.task_id?H(X):X):$.pending}}return $}function e6($){if($.pending.length===0)return $;return{active:[...$.active,...$.pending.map((Z)=>({...Z,isBackgrounded:!0}))],pending:[]}}function $7($,Z,J=Date.now()){let Y=Z.status==="completed"?"completed":Z.status==="failed"?"failed":"killed";if($.pending.some((Q)=>Q.id===Z.task_id))return{active:$.active,pending:$.pending.filter((Q)=>Q.id!==Z.task_id)};if($.active.some((Q)=>Q.id===Z.task_id))return{active:$.active.map((Q)=>Q.id===Z.task_id?{...Q,status:Y,usage:Z.usage??Q.usage,summary:Z.summary??Q.summary,endTime:Q.endTime??J}:Q),pending:$.pending};return $}function F4($){let Z=0,J=0;for(let Y=$.length-1;Y>=0;Y--)if(Z+=$[Y].brief.length+5,Z>yV){J=Y+1;break}return J===0?$:$.slice(J)}function xV($,Z){let J=(Y)=>typeof Y==="string"?Y:"";switch($){case"Bash":return R1(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 bV($,Z){let J=($??"").replace(/\s+/g," ").trim();return Z?`❌ ${J.slice(0,80)}`:J.slice(0,80)}function Z7($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((V)=>V.toolUseId===Z),H=$.pending.some((V)=>V.toolUseId===Z);if(!W&&!H)return $;let X=(V)=>V.map((z)=>z.toolUseId===Z?{...z,steps:F4([...z.steps,{toolUseId:J,tool:Y,brief:`${Y} ${xV(Y,Q)}`.trim()}])}:z);return{active:W?X($.active):$.active,pending:H?X($.pending):$.pending}}function J7($,Z,J,Y,Q,W){let H=$.active.some((z)=>z.id===Z),X=$.pending.some((z)=>z.id===Z);if(!H&&!X)return $;let V=(z)=>z.map((G)=>{if(G.id!==Z)return G;if(Q==="started")return{...G,steps:F4([...G.steps,{toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()}])};let _=!1,B=G.steps.map((q)=>{if(_||q.toolUseId!==J)return q;return _=!0,{...q,brief:W?`${q.brief} ${W}`:q.brief}});if(!_&&W)B.push({toolUseId:J,tool:Y,brief:`${Y} ${W}`.trim()});return{...G,steps:F4(B)}});return{active:H?V($.active):$.active,pending:X?V($.pending):$.pending}}function Y7($,Z,J,Y,Q){if(!Z)return $;let W=$.active.some((V)=>V.toolUseId===Z),H=$.pending.some((V)=>V.toolUseId===Z);if(!W&&!H)return $;let X=(V)=>V.map((z)=>{if(z.toolUseId!==Z)return z;let G=!1,_=z.steps.map((B)=>{if(G||B.toolUseId!==J)return B;return G=!0,{...B,brief:`${B.brief} → ${bV(Y,Q)}`}});return{...z,steps:F4(_)}});return{active:W?X($.active):$.active,pending:H?X($.pending):$.pending}}function n6($){if(!$||$<0)return"0s";let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let J=Math.floor(Z/60);if(J<60)return`${J}m${Z%60}s`;return`${Math.floor(J/60)}h${J%60}m`}function Y3($){let Z=Number.isFinite($)?Math.max(0,$):0;for(let W of fV)if(Z<W.limit)return{label:W.label,nextDelayMs:W.limit-Z};let J=600000,Y=Math.floor((Z-600000)/J),Q=600000+(Y+1)*J;return{label:`${(Y+1)*10}m+`,nextDelayMs:Q-Z}}function L$($,Z="bucket"){if(Z==="second"){let J=Number.isFinite($)?Math.max(0,$):0;if(J>=a6){let Y=Math.floor((J-a6)/Z3),Q=a6+(Y+1)*Z3;return{label:`${10+Y*5}m+`,nextDelayMs:Q-J}}return{label:`${Math.floor(J/1000)}s`,nextDelayMs:J3}}return Y3($)}function vV($){return $.subagentType??$.workflowName??wV[$.type]}function o6($){if($.usage?.duration_ms)return $.usage.duration_ms;if($.endTime&&$.endTime>$.startedAt)return $.endTime-$.startedAt;return 0}function hV($,Z,J="bucket"){let Y=(Q)=>L$(Q,J).label;switch($.status){case"running":return`\uD83D\uDFE1 运行中 (${Y(Z-$.startedAt)})`;case"paused":return`⏸️ 已暂停 (${Y(Z-$.startedAt)})`;case"pending":return"⚪ 等待中";case"completed":return`✅ 用时 ${n6(o6($))}`;case"failed":return`❌ 失败 ${n6(o6($))}`;case"killed":return`\uD83D\uDC80 已终止 ${n6(o6($))}`}}function Q3($){let Z=$.filter((Y)=>!x0(Y)).length,J=$.length-Z;if(Z>0)return`${Z} 进行中${J?` · ${J} 已结束`:""}`;return J?`${J} 已结束`:"空"}function U4($){return`\uD83E\uDDED 后台任务 · ${Q3($)}`}function gV($){let Z=[];if($.error)Z.push(`⚠ ${$.error}`);if(x0($)&&$.summary)Z.push(`\uD83D\uDCDD ${$.summary.slice(0,400)}`,"");for(let J=0;J<$.steps.length;J++)Z.push(`${J+1}. ${$.steps[J].brief}`);return d(Z.length>0?Z.join(`
46
+ `):"_(暂无执行记录)_")}function U1($,Z=Date.now(),J="bucket"){return{tag:"collapsible_panel",element_id:A2.panel($.id),header:{title:{tag:"plain_text",content:`${CV[$.type]} ${vV($)} · ${$.description||"(无描述)"} — ${hV($,Z,J)}`}},expanded:!1,elements:[{tag:"markdown",element_id:A2.body($.id),content:gV($)}]}}function Q7($,Z=Date.now(),J="bucket"){return{schema:"2.0",config:{streaming_mode:!0,summary:{content:U4($)}},body:{elements:$.map((Y)=>U1(Y,Z,J))}}}function O4($,Z=Date.now(),J="bucket"){let Y=$.filter(x0);return{schema:"2.0",config:{streaming_mode:!1,summary:{content:`\uD83E\uDDED 后台任务(历史) · ${Y.length} 已结束`}},body:{elements:Y.map((Q)=>U1(Q,Z,J))}}}function W7(){return{schema:"2.0",config:{streaming_mode:!1,summary:{content:"↪ 后台任务进行中"}},body:{elements:[{tag:"markdown",element_id:"bg_marker",content:"↪ 本轮后台任务仍在进行,进度已迁至最新卡片"}]}}}var A2,yV=1000,CV,wV,fV,J3=1000,a6=600000,Z3=300000;var H7=N(()=>{y0();L4();A2={panel:($)=>`bg_${eZ($)}`,body:($)=>`bgb_${eZ($)}`};CV={subagent:"\uD83D\uDFE2",shell:"⚙️",monitor:"\uD83D\uDCE1",workflow:"\uD83D\uDD01",unknown:"\uD83D\uDD39"},wV={subagent:"子agent",shell:"shell",monitor:"监控",workflow:"工作流",unknown:"任务"};fV=[{limit:30000,label:"<30s"},{limit:60000,label:"<1m"},{limit:180000,label:"<3m"},{limit:300000,label:"<5m"},{limit:600000,label:"<10m"}]});function a0($){return typeof $==="string"&&IV.includes($)}function O1($){return $?.startsWith("claude:")?"claude":"codex"}function J$($){return $==="claude"?"Claude":"Codex"}var IV,P$="max",_2;var I$=N(()=>{IV=["low","medium","high","xhigh","max"];_2=class _2 extends Error{constructor($="上下文窗口充足,无需压缩"){super($);this.name="NothingToCompactError"}}});function j$($){return $.startsWith("claude:")?$:`claude:${$}`}function X7($){if(!$||$==="default"||$==="claude:default")return"opus";if(!$.startsWith("claude:"))return $;let Z=$.slice(7);if(Z==="glm"||Object.hasOwn(v.claude.models,Z))return v.claude.models[Z]?.model?.trim()||"opus";return Z}var W3=N(()=>{U0()});import{existsSync as cV,readFileSync as mV}from"node:fs";function V7(){return process.env.LODESTAR_DATA_DIR?`${process.env.LODESTAR_DATA_DIR.replace(/\/+$/,"")}/context-window-cache.json`:WZ}function B2(){if(K2!==null)return K2;try{K2=cV(V7())?JSON.parse(mV(V7(),"utf8")):{}}catch($){A(`context-window-observe: cache read MISS (${$?.message??$}), starting fresh`),K2={}}return K2??{}}function pV(){try{H0(V7(),B2())}catch($){A(`context-window-observe: cache write MISS (${$?.message??$})`)}}function z7($,Z){return`${$}:${Z.replace(/\[1m\]$/,"")}`}function H3($,Z,J){if(!Number.isFinite(J)||J<=0)return;let Y=z7($,Z),Q=B2()[Y];if(Q===J)return;B2()[Y]=J,pV(),A(`context-window-observe: ${Y} → ${J} (prev ${Q??"-"})`)}function E4($,Z){if(!Z)return;if(Z.endsWith("[1m]"))return Z;let J=B2()[z7($,Z)];return J!=null&&J<uV?Z:`${Z}[1m]`}function T4($,Z){return B2()[z7($,Z)]}var uV=1e6,K2=null;var N4=N(()=>{L0();I();I0()});import{existsSync as S4,readFileSync as q3}from"node:fs";import{homedir as q2}from"node:os";import{spawn as lV}from"cross-spawn";import{delimiter as X3,join as c$,posix as iV,win32 as dV}from"node:path";import{EventEmitter as nV}from"node:events";import{query as aV}from"@anthropic-ai/claude-agent-sdk";function oV($,Z){if(!Z||$.includes("user"))return{};return{plugins:[{type:"local",path:Z,skipMcpDiscovery:!0}],skills:"all"}}function rV($){return $==="win32"?";":":"}function A7($,...Z){return $==="win32"?dV.join(...Z):iV.join(...Z)}function V3($){let Z=$.toLowerCase();return Z.endsWith(".cmd")||Z.endsWith(".bat")}function z3($){let Z=lV($.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 P3($={}){let Z=$.platform??process.platform,J=$.exists??S4,Y=$.homeDir??q2();if(Z!=="win32"){let W=[A7(Z,Y,".local","npm-global","bin","claude"),A7(Z,Y,".local","bin","claude")];for(let H of W)if(J(H))return H}let Q=sV($);if(Q)return Q;return null}function j3(){P3()}function tV($={}){let Z=$.platform??process.platform,J=$.configuredBin===void 0?v.claude.bin:$.configuredBin;if(J){if(!($.exists??S4)(J))throw Error(`lodestar: [claude].bin not found: ${J} (config.toml)`);if(Z==="win32"&&V3(J))return{pathToClaudeCodeExecutable:J,spawnClaudeCodeProcess:z3,description:`windows-shell-shim:${J}`};return{pathToClaudeCodeExecutable:J,description:`config:${J}`}}let Y=P3($);if(!Y)return{description:"sdk-default"};if(Z==="win32"&&V3(Y))return{pathToClaudeCodeExecutable:Y,spawnClaudeCodeProcess:z3,description:`windows-shell-shim:${Y}`};return{description:"sdk-default"}}function sV($={}){let Z=$.platform??process.platform,J=$.pathEnv??process.env.PATH??"";if(!J)return null;let Y=$.exists??S4,Q=Z==="win32"?["claude.exe","claude.cmd","claude.bat","claude"]:["claude"];for(let W of J.split(rV(Z))){if(!W)continue;for(let H of Q){let X=A7(Z,W,H);if(Y(X))return X}}return null}function G3(){if(process.platform==="win32")return process.env.PATH??"";let $=[c$(q2(),".local","npm-global","bin"),c$(q2(),".local","bin"),c$(q2(),".bun","bin"),...(process.env.PATH??"").split(X3),"/usr/local/bin","/usr/bin","/bin"];return[...new Set($.filter(Boolean))].join(X3)}function eV($){let Z=j1($);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 A3($){if(!$)return null;let Z=($.input_tokens??0)+($.cache_read_input_tokens??0)+($.cache_creation_input_tokens??0);return Z>0?Z:null}function K7($){let Z=$.replace(/[^a-zA-Z0-9]/g,"-"),J=process.env.CLAUDE_CONFIG_DIR||c$(q2(),".claude");return c$(J,"projects",Z)}function B7($,Z){return c$(K7($),`${Z}.jsonl`)}function $z($){let Z;try{Z=q3($,"utf8")}catch{return null}let J=Z.split(`
47
+ `);for(let Y=J.length-1;Y>=0;Y--){let Q=J[Y].trim();if(!Q)continue;try{let W=JSON.parse(Q);if(W?.type==="assistant"&&W?.message?.usage){let H=W.message.usage;if((H.input_tokens??0)+(H.cache_read_input_tokens??0)+(H.cache_creation_input_tokens??0)+(H.output_tokens??0)>0)return H}}catch{}}return null}function K3($,Z){let J=Z?.trim()||"no-source",Y=$&&$.trim()?$:"claude:default";return`${J}:${Y}`}function Zz($){if(!$||typeof $!=="object")return{usage:null,contextWindow:null};let Z={},J=null;for(let Q of Object.values($)){if(!Q||typeof Q!=="object")continue;let W=Q;Z.input_tokens=(Z.input_tokens??0)+E1(W.inputTokens??W.input_tokens),Z.output_tokens=(Z.output_tokens??0)+E1(W.outputTokens??W.output_tokens),Z.reasoning_output_tokens=(Z.reasoning_output_tokens??0)+E1(W.reasoningOutputTokens??W.reasoning_output_tokens),Z.cache_read_input_tokens=(Z.cache_read_input_tokens??0)+E1(W.cacheReadInputTokens??W.cache_read_input_tokens),Z.cache_creation_input_tokens=(Z.cache_creation_input_tokens??0)+E1(W.cacheCreationInputTokens??W.cache_creation_input_tokens);let H=E1(W.contextWindow??W.context_window);if(H>0)J=Math.max(J??0,H)}let Y=(Z.input_tokens??0)+(Z.output_tokens??0)+(Z.cache_creation_input_tokens??0)+(Z.cache_read_input_tokens??0);if(Y<=0)return{usage:null,contextWindow:J};return Z.total_tokens=Y,{usage:Z,contextWindow:J}}function k4($){return{...$}}function G7($){if(!$||typeof $!=="object")return[];return Object.keys($).slice(0,20)}function Jz($,Z){let J=$?{...$}:{},Y=(Q)=>{let W=Z[Q];if(typeof W!=="number"||!Number.isFinite(W))return;J[Q]=(J[Q]??0)+W};return Y("total_tokens"),Y("input_tokens"),Y("output_tokens"),Y("reasoning_output_tokens"),Y("cache_creation_input_tokens"),Y("cache_read_input_tokens"),J}function E1($){return typeof $==="number"&&Number.isFinite($)?$:0}function R3($){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(`
48
+ `);return $==null?"":JSON.stringify($,null,2)}function Yz($){let Z=R3($);try{let J=JSON.parse(Z);if(Array.isArray(J)){let Y=J.map((Q)=>{if(typeof Q==="string")return Q;if(Q&&typeof Q==="object"&&typeof Q.text==="string")return Q.text;return JSON.stringify(Q)}).filter(Boolean);if(Y.length>0)return Y.join(`
49
+ `)}}catch{}return Z}function Qz($){return`server_tool:${$}`}function Wz($){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 Hz($){let Z=$.trim();return Z.includes("Built-in Tool:")||Z.startsWith("**Output:**")&&Z.includes("_result")}function Xz($){let Z=$.supportedEffortLevels&&$.supportedEffortLevels.length>0?$.supportedEffortLevels:[P$];return{id:j$($.value),model:j$($.value),displayName:$.displayName||j$($.value),description:$.description||"Claude Agent SDK backend",hidden:!1,isDefault:!1,supportedReasoningEfforts:Z.map((J)=>({reasoningEffort:J,description:""})),defaultReasoningEffort:Z.includes(P$)?P$:Z[0]}}function zz($){if(!$?.settingSources)return[...B3];let Z=$.settingSources.split(",").map((J)=>J.trim()).filter(Boolean);return Z.length?Z:[...B3]}function Gz($){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 Az($){let Z=c$($,".mcp.json"),J;try{J=q3(Z,"utf8")}catch(Y){if(Y.code!=="ENOENT")A(`claude-agent-process: project .mcp.json not readable at ${Z}: ${Y}`);return}try{let Y=JSON.parse(J);if(Y&&typeof Y==="object"&&Y.mcpServers&&typeof Y.mcpServers==="object")return Y.mcpServers;A(`claude-agent-process: project .mcp.json has no mcpServers object at ${Z}`);return}catch(Y){A(`claude-agent-process: project .mcp.json parse failed at ${Z}: ${Y}`);return}}function _z($){let Z=$.questions;return(Array.isArray(Z)?Z:Z&&typeof Z==="object"?[Z]:[$]).map((Y)=>Kz(Y)).filter((Y)=>Y!==null)}function Kz($){let Z=$&&typeof $==="object"?$:{question:$},J=_7(Z.question,Z.prompt,Z.title,Z.message,Z.text,Z.label);if(!J)return null;if(!J.trim())return null;let Y=Bz(Z.options??Z.choices??Z.suggestions);return{...Z,question:J,options:Y,...typeof Z.header==="string"?{header:Z.header}:{},...typeof Z.multiSelect==="boolean"?{multiSelect:Z.multiSelect}:{}}}function Bz($){if(!Array.isArray($))return[];let Z=[];for(let J of $){if(typeof J==="string"){Z.push({label:J});continue}if(!J||typeof J!=="object")continue;let Y=J,Q=_7(Y.label,Y.value,Y.text,Y.title);if(!Q?.trim())continue;let W=_7(Y.description,Y.detail,Y.preview);Z.push(W?{label:Q,description:W}:{label:Q})}return Z}function _7(...$){for(let Z of $)if(typeof Z==="string")return Z;return}var L3,_3,Vz="default",B3,q7;var y4=N(()=>{U0();I();I$();W3();N4();L3=class L3{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($))}};_3=new Map;B3=["project","local"];q7=class q7 extends nV{provider="claude";tokenSourceId;opts;input=new L3;query=null;abortController=new AbortController;alive=!0;expectedExit=!1;exitPromise;resolveExit;started=!1;pendingPermissions=new Map;requestCounter=0;cumulativeUsageFromResults=null;turnActive=!1;emittedToolUseIds=new Set;emittedToolResultIds=new Set;pendingServerToolInputs=[];sessionId=null;lastAssistantUuid=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;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?j$($.model):null}sendInitialize(){if(this.started)return;this.started=!0;let $=X7(this.opts.model),Z=this.opts.profile;if(Z)A(`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??zz(Z),Y=oV(J,this.opts.managedSkillPluginPath),Q=Gz(Z),W=Z?.strictMcp===!0,H=Z?.loadProjectMcp!==!1?Az(this.opts.workDir):void 0;try{let X=tV();A(`claude-agent-process: spawn SDK query model=${$??"default"} effort=${this.opts.effort} cwd=${this.opts.workDir} executable=${X.description}`),this.query=aV({prompt:this.input,options:{cwd:this.opts.workDir,abortController:this.abortController,...$?{model:$}:{},effort:this.opts.effort,resume:this.opts.resumeSessionId,...this.opts.resumeSessionAt?{resumeSessionAt:this.opts.resumeSessionAt}:{},...this.opts.forkSession?{forkSession:!0}:{},...X.pathToClaudeCodeExecutable?{pathToClaudeCodeExecutable:X.pathToClaudeCodeExecutable}:{},...X.spawnClaudeCodeProcess?{spawnClaudeCodeProcess:X.spawnClaudeCodeProcess}:{},permissionMode:Vz,env:this.opts.transformEnv?this.opts.transformEnv({...process.env,PATH:G3(),...v.claude.env,...this.opts.hostEnv??{}}):{...process.env,PATH:G3(),...v.claude.env,...this.opts.hostEnv??{}},settingSources:[...J],...Y,tools:Q,...this.opts.allowDelegation===!1?{disallowedTools:["Agent","Task"]}:{},...W?{strictMcpConfig:!0}:{},...H?{mcpServers:H}:{},toolConfig:{askUserQuestion:{previewFormat:"markdown"}},canUseTool:(V,z,G)=>this.canUseTool(V,z,G),includePartialMessages:!1,systemPrompt:{type:"preset",preset:"claude_code",...this.opts.appendSystemPrompt?{append:this.opts.appendSystemPrompt}:{}},stderr:(V)=>{let z=V.trim();if(z)A(`claude-agent-process[stderr]: ${z}`)}}})}catch(X){let V=X instanceof Error?X:Error(String(X));this.emit("error",V),this.finishExit(1,null);return}this.readLoop(this.query)}sendUserText($,Z=[]){if(!this.alive){A("claude-agent-process: sendUserText ignored on dead process");return}if(!this.started)this.sendInitialize();let J=Z.length?Z.map((Y)=>`[file: ${Y}]`).join(" ")+`
50
50
 
51
- `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let Q=Y instanceof Error?Y:Error(String(Y));G(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>G(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){G(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Y.cleanup?.(),Z==="allow")Y.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Y.resolve({behavior:"deny",message:J?.denyMessage??""})}sendHookResponse($,Z={}){G("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 G(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw G(`claude-agent-process: kill failed: ${J.message}`),J}}async listModels(){if(!this.started)this.sendInitialize();if(!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");return(await this.query.supportedModels()).map(dV)}async setModelSettings($,Z){let J=n9($);if(!n$(Z))throw Error(`invalid Claude effort: ${String(Z)}`);if(!this.started)this.sendInitialize();if(!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");if(J)await this.query.setModel(J);if(Z==="max")await this.query.applyFlagSettings({ultracode:!0,effortLevel:null});else await this.query.applyFlagSettings({effortLevel:Z,ultracode:null});this.opts.model=$,this.opts.effort=Z,this.lastModel=J?R0($):"claude:default",this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Y=()=>{this.off("context_compacted",Q),this.off("assistant_text",W),this.off("exit",H),this.off("error",X)},Q=()=>{if(J)return;J=!0,Y(),$()},W=(V)=>{if(J)return;if((V?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new Q2)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},X=(V)=>{if(J)return;J=!0,Y(),Z(V instanceof Error?V:Error(String(V)))};this.on("context_compacted",Q),this.on("assistant_text",W),this.once("exit",H),this.once("error",X)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=tV(Z);if(Y.length===0)return G("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},W=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||W,X={request_id:W,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},V=new Promise((z)=>{let A=(B)=>{J.signal.removeEventListener("abort",K),z(B)},K=()=>{if(!this.pendingPermissions.delete(W))return;A({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",K,{once:!0}),this.pendingPermissions.set(W,{kind:"dialog",resolve:A,request:X})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",X),V}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){G(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}G(`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(),G(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:G(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=R0($.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.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":G(`claude-agent-process: api retry attempt=${$.attempt}/${$.max_retries} status=${$.error_status} error=${$.error}`);return;case"permission_denied":G(`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){G("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){G(`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:G(`claude-agent-process: unhandled system subtype=${String($.subtype??"unknown")}`);return}}handleAssistantMessage($){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=R0(Z.model);let Y=Array.isArray(Z?.content)?Z.content:[];for(let Q of Y){if(!Q||typeof Q!=="object")continue;if(Q.type==="text"&&typeof Q.text==="string"&&Q.text.length>0){let W=lV(Q.text);if(W){if(this.pendingServerToolInputs.push(W),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(iV(Q.text))continue;let H=$.uuid??Z?.id;this.emit("assistant_text",{uuid:H,text:Q.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:H,parentToolUseId:J})}else if(Q.type==="tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Q.name,Q.input??{},J);else if(Q.type==="server_tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,pV(Q.name),{tool:Q.name,input:this.serverToolInput(Q.name,Q.input??{})},J);else if(Q.type==="tool_result"&&typeof Q.tool_use_id==="string")this.emitToolResultOnce(Q.tool_use_id,uV(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;this.emittedToolUseIds.add($),this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Y})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Y=this.pendingServerToolInputs.findIndex((Q)=>Q.name===$);if(Y>=0){let[Q]=this.pendingServerToolInputs.splice(Y,1);return Q.input}return J}emitToolResultOnce($,Z,J,Y){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Y})}handleUserMessage($){let Z=$.message?.content;if($.isMeta===!0&&$.promptSource==="sdk"&&typeof Z==="string"&&Z.trim())this.emit("scheduled_turn_input",{text:Z,promptId:typeof $.promptId==="string"&&$.promptId?$.promptId:null});let J=Array.isArray(Z)?Z:[];for(let Y of J){if(!Y||typeof Y!=="object")continue;if(Y.type!=="tool_result"||typeof Y.tool_use_id!=="string")continue;let Q=$.tool_use_result,W=Y3(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
52
- `):"",X=W||H;this.emitToolResultOnce(Y.tool_use_id,X,Y.is_error===!0||Q?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=gV($.usage),J=$.modelUsage??$.model_usage,Y=cV(J);if(!Z&&!Y.usage)G(`claude-agent-process: result usage missing rootKeys=${r9($).join(",")||"-"} usageKeys=${r9($.usage).join(",")||"-"} modelUsageKeys=${r9(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=D4(Y.usage),this.lastTotalUsage=D4(Y.usage);else if(Z)this.cumulativeUsageFromResults=mV(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=D4(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?D4(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=tZ(this.opts.model,this.tokenSourceId);if(rZ.set(X,Y.contextWindow),this.tokenSourceId)for(let[V,z]of Object.entries(J??{})){let A=z?.contextWindow;if(typeof A==="number"&&A>0)lZ(this.tokenSourceId,V,A)}}this.lastContextWindow=rZ.get(tZ(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=$8(this.opts.workDir,this.sessionId??""),W=IV(Q);if(this.lastContextTokens=oZ(W)??(j4(Q)?oZ(Z):null),this.lastTotalUsage||this.lastUsage)this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:this.sessionId??void 0,turnId:$.uuid});let H=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof $.duration_ms==="number"?$.duration_ms:null,num_turns:typeof $.num_turns==="number"?$.num_turns:1,usage:this.lastUsage,subtype:H,is_error:$.is_error===!0||H!=="success"},this.emit("result",{subtype:H,is_error:this.lastResult.is_error,...this.lastResult.is_error?{error:Array.isArray($.errors)&&$.errors.length?$.errors.map(String).join(`
53
- `):String($.result??$.error??$.api_error_message??H)}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,checkpoint:!this.lastResult.is_error&&this.lastAssistantUuid&&this.sessionId?{provider:"claude",kind:"assistant-message",id:this.lastAssistantUuid,source:{provider:"claude",sessionId:this.sessionId,cwd:this.opts.workDir}}:null})}failTurnStart($){this.turnActive=!1,this.lastAssistantUuid=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"claude_turn_start_failed",is_error:!0},this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:$.message})}}});var X3={};G1(X3,{waitForTokenSourceModelRefresh:()=>O4,tokenSourceFactories:()=>U1,setDefaultTokenSource:()=>Y8,scrubAnthropicEnv:()=>g0,resetTokenSourceRegistry:()=>Q8,registerTokenSourceFactory:()=>J0,registerTokenSource:()=>J8,refreshAllTokenSourceModels:()=>z2,pendingTokenSourceModelRefresh:()=>O1,listTokenSourcesByAgent:()=>H3,listTokenSources:()=>I0,listEnabledTokenSourcesByAgent:()=>U4,getTokenSource:()=>e});function g0($){let Z={...$};for(let J of $z)delete Z[J];return Z}function J0($){Q3.set($.kind,$)}function U1(){return[...Q3.values()]}function J8($,Z){if(V2.set($.id,$),Z?.default||F4===null)F4=$.id}function e($){return $?V2.get($):void 0}function I0(){return[...V2.values()]}function H3($){return I0().filter((Z)=>Z.agent===$)}function U4($){return H3($).filter((Z)=>Z.enabled)}function Y8($){if(V2.has($))F4=$}function Q8(){V2.clear(),F4=null,W3++}function z2(){let $=W3;if(F1?.generation===$)return F1.promise;let Z=Promise.allSettled(I0().map(async(J)=>{await J.refreshModels(),G(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(F1?.promise===Z)F1=null});return F1={generation:$,promise:Z},Z}function O1(){return F1?.promise??null}async function O4(){let $;while($=O1())await $}var $z,Q3,V2,F4=null,W3=0,F1=null;var G$=S(()=>{g();$z=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL"];Q3=new Map;V2=new Map});function E4($){let Z=$.tokenSourceId?e($.tokenSourceId):void 0;if($.tokenSourceId&&!Z)throw Error(`token source not found: ${$.tokenSourceId}`);if(Z&&!Z.enabled)throw Error(`token source disabled: ${Z.id}`);if(Z&&Z.agent!==$.provider)throw Error(`token source ${Z.id} belongs to ${Z.agent}, not ${$.provider}`);if(Z?.modelCatalogState?.status==="failed")throw Error(`model catalog refresh failed for ${Z.id}: ${Z.modelCatalogState.error??"MISS"}`);if(Z?.modelCatalogState?.status==="idle"||Z?.modelCatalogState?.status==="loading")throw Error(`model catalog is not ready for ${Z.id}: ${Z.modelCatalogState.status}`);let J=$.model??Z?.defaultModel;if(Z&&J&&!Z.models.some((W)=>W.model===J))throw Error(`model is not present in token source ${Z.id}: ${J}`);let Y=Z&&J?Z.resolveSpawnModel(J):J;if(J&&!Y)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${J}`);let Q=Z?(W)=>Z.spawnEnv(W):void 0;if($.provider==="claude"){if(J3(),!n$($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new Z8({workDir:$.workDir,model:Y,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}:{},...Z?{settingSources:Z.settingSources??["project","local"]}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:Z?.id??null,transformEnv:Q,hostEnv:$.hostEnv}),sourceRevision:Z?.spawnRevision??null}}if($.effort!==void 0&&!k$($.effort))throw Error(`invalid Codex effort: ${$.effort}`);return{process:new L1({workDir:$.workDir,model:Y,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:Z?.id??null,transformEnv:Q,hostEnv:$.hostEnv,serviceName:$.serviceName}),sourceRevision:Z?.spawnRevision??null}}var W8=S(()=>{v0();M4();P1();G$()});function T4($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}async function H8($){let Z=await z8("feishu chat.get",()=>r.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)N4("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 X8($,Z){let J=await z8("feishu tasklist.create",()=>r.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)N4("feishu tasklist.create",J);let Y=J.data?.tasklist,Q=Y?.guid;if(!Q)throw Error("feishu tasklist.create returned no guid");return{guid:Q,name:Y?.name||$,url:Y?.url??"",createdAt:Y?.created_at}}async function V8($){let Z=await z8("feishu tasklist.delete",()=>r.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)N4("feishu tasklist.delete",Z)}function V3($,Z){let J=Z&&typeof Z==="object"?Z:{},Y=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Q=Y.code??J.code,W=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,X=Array.isArray(H)?H.map((V)=>V?.scope??V?.subject??V?.name??V).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${W}${X?` missing_scopes=${X}`:""}`}async function z8($,Z){try{return await Z()}catch(J){N4($,J)}}function N4($,Z){throw Error(V3($,Z))}var z3=S(()=>{o()});var $$={};G1($$,{writeAliveMarker:()=>L2,urgentApp:()=>l0,uploadImageKey:()=>w8,uploadAndSend:()=>v8,updateCard:()=>Q0,unbindSessionChat:()=>y4,tempProjectName:()=>a$,tempChatName:()=>U8,setPendingConversationLaunchChecked:()=>L0,sendTextRaw:()=>C,sendText:()=>N,sendImage:()=>f3,sendFile:()=>w3,sendCard:()=>i,sanitizeSessionName:()=>M2,resolveProjectDir:()=>b4,replaceTurnAnchors:()=>c$,registerTempSessionLease:()=>R8,refreshChatList:()=>P2,readAliveMarker:()=>S8,provisionProject:()=>h8,projectProfile:()=>T1,preferredChatForSession:()=>J$,loadTempSessionLeases:()=>q8,loadSessionTurnsMap:()=>M8,loadSessionResumeMap:()=>D8,loadSessionModelMap:()=>O8,loadSessionChatMap:()=>P8,listNormalChatIdsByName:()=>f4,isOpenAIChatGPTAuthenticated:()=>j2,hasTempSessionLease:()=>L8,getTurnAnchors:()=>B2,getTenantToken:()=>Y0,getSessionResumeRef:()=>p0,getSessionModelSelection:()=>N8,getSessionBranchBase:()=>q2,getPendingConversationLaunch:()=>R2,formatFeishuApiError:()=>V3,findNormalChatIdByName:()=>w4,fetchChatOwnerOpenId:()=>H8,fetchChatName:()=>f8,ensureChatForSession:()=>y8,downloadAttachment:()=>D2,disbandChatForSessionExact:()=>b8,disbandChatForSession:()=>C8,deleteTasklistByGuid:()=>V8,deleteReaction:()=>P$,createTempChatForSession:()=>x8,createTasklistWithOwner:()=>X8,client:()=>r,clearSessionResumeChecked:()=>N1,clearSessionConversationState:()=>k8,chatNameCache:()=>Y$,chatIdForSession:()=>k1,bindSessionToChat:()=>E1,bindSessionResumeChecked:()=>_2,bindSessionModelChecked:()=>T8,bindSessionModel:()=>E8,appendTurnAnchorChecked:()=>F8,addReaction:()=>T$,PROJECTS_ROOT:()=>O3});import*as R3 from"@larksuiteoapi/node-sdk";import{execSync as L3}from"node:child_process";import{randomUUID as B8}from"node:crypto";import{existsSync as Zz,mkdirSync as A8,readFileSync as m0,statSync as P3,writeFileSync as D3}from"node:fs";import{readFile as j3}from"node:fs/promises";import{homedir as G3}from"node:os";import{basename as c0,extname as Jz,isAbsolute as M3,join as S4}from"node:path";function K8(){let $={};for(let[Z,J]of E$)$[Z]=J;H$(H9,$)}function q8(){E$.clear();try{let $=JSON.parse(m0(H9,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Y=J;if(typeof Z!=="string"||!Z||Y.chatId!==Z||typeof Y.sessionName!=="string"||!a$(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){G(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}E$.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}G(`feishu: loaded ${E$.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")G(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function R8($,Z){if(!a$($))throw Error(`refusing to lease non-temporary session name "${$}"`);if(!Z)throw Error("cannot lease a temporary session without chat_id");for(let Q of E$.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=E$.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};E$.set(Z,Y);try{K8()}catch(Q){if(J)E$.set(Z,J);else E$.delete(Z);throw Q}}function L8($,Z){let J=E$.get(Z);return J?.sessionName===$&&J.chatId===Z}function T1($){return v.projects[$]}function b4($){return T1($)?.cwd?.trim()||S4(O3,$)}function u0($,Z={}){return fetch($,{...Z,signal:Z.signal??AbortSignal.timeout(Yz)})}async function Y0(){if(k4&&Date.now()<A3)return k4;return G8??=(async()=>{let $=await u0("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:F3,app_secret:U3})}),Z=await $.json();if(!$.ok||!Z.tenant_access_token)throw Error(`feishu: tenant token failed HTTP ${$.status} code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);return k4=Z.tenant_access_token,A3=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,k4})().finally(()=>{G8=null}),G8}function P8(){try{let $=JSON.parse(m0(J9,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")J$.set(Z,J);G(`feishu: loaded ${J$.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function E3(){try{_8()}catch($){G(`feishu: save session-chat-map failed: ${$}`)}}function _8(){let $={};for(let[Z,J]of J$)$[Z]=J;H$(J9,$)}function E1($,Z){if(J$.get($)===Z)return;let J=J$.get($);J$.set($,Z),E3(),G(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function y4($){let Z=J$.get($);if(!Z)return;J$.delete($),E3(),G(`feishu: unbound session "${$}" from ${Z}`)}function A2($,Z){let J=Z$.get($)??{};J[Z.provider]=Z,Z$.set($,J)}function K3($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=J.provider==="claude"||J.provider==="codex"?J.provider:Z??null;if(!Y||Z&&Y!==Z)return null;let Q=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Q)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Y,sessionId:Q,cwd:null};if(typeof J.cwd!=="string"||!M3(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function _3($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if($.provider!=="codex"&&$.provider!=="claude")throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!M3($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function Qz($,Z,J){if(typeof $!=="string")return _3($);if(!Z)throw Error("cannot bind a conversation without a provider");return _3({provider:Z,sessionId:$,cwd:J??null})}function D8(){try{let $=JSON.parse(m0(Y9,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");Z$.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){A2(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=K3(Y);if(Q){A2(Z,Q);continue}for(let W of["codex","claude"]){let H=Y[W];if(typeof H==="string"&&H.trim()){A2(Z,{provider:W,sessionId:H.trim(),cwd:null});continue}let X=K3(H,W);if(X)A2(Z,X)}}G(`feishu: loaded ${Z$.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function x4(){let $={};for(let[Z,J]of Z$){let Y={};if(J.codex)Y.codex={...J.codex};if(J.claude)Y.claude={...J.claude};$[Z]=Y}H$(Y9,$)}function _2($,Z,J,Y){let Q=Qz(Z,J,Y),W=Z$.get($),H=W?{...W}:void 0,X=W?.[Q.provider];if(X?.sessionId===Q.sessionId&&X.cwd===Q.cwd)return;A2($,Q);try{x4()}catch(V){if(H)Z$.set($,H);else Z$.delete($);throw V}}function p0($,Z="codex"){let J=Z$.get($)?.[Z];return J?{...J}:null}function N1($,Z){let J=Z$.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)Z$.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)Z$.delete($);else Z$.set($,Q)}try{x4()}catch(Q){throw Z$.set($,Y),Q}}function T3($){if(!$||typeof $!=="object")return null;let Z=$;if(Z.provider!=="claude"&&Z.provider!=="codex")return null;let J=typeof Z.sessionId==="string"?Z.sessionId.trim():"";if(!J)return null;let Y;if(Z.cwd===void 0||Z.cwd===null)Y=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Y=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Y}}function N3($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=T3(J),Q=typeof Z.id==="string"?Z.id.trim():"";if(!Q||!Y)return null;if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Y.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Q,source:{...Y,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Y.provider==="codex")return{provider:"codex",kind:"turn",id:Q,source:{...Y,provider:"codex"}};return null}function k3($){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=T3(Z.source);if(!J)return null;let Y=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Q=N3(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{z$(Y,J.provider)}catch{return null}return Y}function Wz($){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 Hz($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Y=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Q=N3(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let W=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!W||!H)return null;Q={provider:"claude",kind:"assistant-message",id:W,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:Wz(J.writes)}}function Xz($){if(!$||typeof $!=="object")return null;let Z=$,J=k3(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Y=Z.previousSessionId,Q=Y===null?null:typeof Y==="string"&&Y.trim()?Y.trim():void 0;if(Q===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Q}}function j8($){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 M8(){try{let $=JSON.parse(m0(Q9,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");l.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let W,H,X=null;if(Array.isArray(Q))W=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let K=Q;if(!Array.isArray(K.anchors)||!Object.prototype.hasOwnProperty.call(K,"base")){J++;continue}if(W=K.anchors,K.base===null)H=null;else{let B=k3(K.base);if(!B){J++;continue}H=B}if(Object.prototype.hasOwnProperty.call(K,"pendingLaunch")){let B=Xz(K.pendingLaunch);if(!B){J++;continue}X=B}}else{J++;continue}let V=Z$.get(Y),z=V?.claude!==void 0&&V.codex===void 0?"claude":null,A=[];for(let K of W){let B=Hz(K,z);if(B)A.push(B);else J++}if(A.length||H!==null||X)l.set(Y,{base:H,anchors:A,...X?{pendingLaunch:X}:{}}),Z+=A.length}if(G(`feishu: loaded ${Z} turn anchors across ${l.size} sessions`),J>0)G(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function K2(){let $={};for(let[Z,J]of l)$[Z]=J;H$(Q9,$)}function F8($,Z){let J=l.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>B3){let W=Y.splice(0,Y.length-B3),H=W[W.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}l.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{K2()}catch(W){if(J)l.set($,J);else l.delete($);throw W}}function B2($){return l.get($)?.anchors??[]}function q2($){return l.get($)?.base??null}function R2($){let Z=l.get($)?.pendingLaunch;return Z?j8(Z):null}function L0($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");z$(Z.launch,"claude",Z.launch.source.cwd)}let J=l.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)l.delete($);else l.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:j8(Z)}:{}});try{K2()}catch(W){if(J)l.set($,J);else l.delete($);throw W}}function c$($,Z,J,Y){let Q=l.get($),W=Y===void 0?Q?.pendingLaunch:Y??void 0,H=W?j8(W):void 0;if(Z.length===0&&J===null&&!H)l.delete($);else l.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{K2()}catch(X){if(Q)l.set($,Q);else l.delete($);throw X}}function a$($){return q3.test($)?$.replace(q3,""):null}function U8($,Z=[]){let J=new Date,Y=(X)=>String(X).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,W=new Set([...Y$.values(),...l.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;W.has(H);X++)H=`${$}*${Q}-${X}`;return H}function O8(){try{let $=JSON.parse(m0(W9,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){L$.set(Z,{provider:j1(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,W=Q==="claude"||Q==="codex"?Q:typeof Y==="string"&&Y.trim()?j1(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(W==="claude"&&!H)continue;let{effort:X,tokenSourceId:V}=J,z=typeof V==="string"&&V.trim()?V.trim():null,A=W==="claude"?n$(X)?X:null:k$(X)?X:null;L$.set(Z,{provider:W,model:H,effort:A,...z?{tokenSourceId:z}:{}})}G(`feishu: loaded ${L$.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")G(`feishu: load session-model-map failed: ${$?.message??$}`)}}function Vz(){try{C4()}catch($){G(`feishu: save session-model-map failed: ${$}`)}}function C4(){let $={};for(let[Z,J]of L$)$[Z]=J;H$(W9,$)}function E8($,Z,J,Y,Q){let W=L$.get($);if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;L$.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),Vz()}function T8($,Z,J,Y,Q){let W=L$.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;L$.set($,H);try{C4()}catch(X){if(W)L$.set($,W);else L$.delete($);throw X}}function N8($){let Z=L$.get($);if(Z)return Z;let J=a$($);return J?L$.get(J)??null:null}function k8($){let Z=J$.get($),J=Z$.get($),Y=L$.get($),Q=l.get($),W=[...E$.entries()].filter(([,H])=>H.sessionName===$);J$.delete($),Z$.delete($),L$.delete($),l.delete($);for(let[H]of W)E$.delete(H);try{_8(),x4(),C4(),K2(),K8()}catch(H){if(Z)J$.set($,Z);if(J)Z$.set($,J);if(Y)L$.set($,Y);if(Q)l.set($,Q);for(let[V,z]of W)E$.set(V,z);let X=[H];for(let V of[_8,x4,C4,K2,K8])try{V()}catch(z){X.push(z)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function L2($){try{H$(t2,$)}catch(Z){G(`feishu: write alive marker failed: ${Z}`)}}function S8(){if(!Zz(t2))return[];try{let $=m0(t2,"utf8"),Z=JSON.parse($);return Array.isArray(Z)?Z.filter((J)=>typeof J==="string"):[]}catch($){return G(`feishu: read alive marker failed: ${$}`),[]}}function k1($){let Z=J$.get($);if(Z){let Y=Y$.get(Z);if(Y&&Y!==$)G(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of Y$)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)G(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function P2(){try{let $;do{let Z=await r.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)Y$.set(J.chat_id,J.name);$=Z.data?.page_token}while($);G(`feishu: refreshed chat list — ${Y$.size} groups`)}catch($){G(`feishu: refresh chat list failed: ${$}`)}}async function f4(){let $=new Map,Z;do{let J=await r.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Y of J.data?.items??[]){if(!Y.chat_id||!Y.name)continue;if(Y.chat_status&&Y.chat_status!=="normal")continue;Y$.set(Y.chat_id,Y.name);let Q=$.get(Y.name)??[];Q.push(Y.chat_id),$.set(Y.name,Q)}Z=J.data?.page_token}while(Z);return $}async function w4($){let Z=J$.get($);if(Z&&Y$.get(Z)===$){let W=await y3(Z);if(W.name===$&&x3(W.status))return Z;Y$.delete(Z),y4($)}let Y=(await f4()).get($)??[];if(Y.length===0)return null;let Q=J$.get($);if(Q&&Y.includes(Q))return Q;if(Y.length===1)return Y[0];throw Error(`multiple Feishu groups named "${$}": ${Y.join(", ")}`)}async function y8($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await w4($);if(J){let W=await zz(J,Z);return E1($,J),{chatId:J,created:!1,joined:W}}let Y=await r.im.chat.create({params:{user_id_type:"open_id",uuid:B8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return Y$.set(Q,$),E1($,Q),{chatId:Q,created:!0,joined:!0}}async function x8($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await w4($))throw Error(`temporary group name already exists: ${$}`);let Y=await r.im.chat.create({params:{user_id_type:"open_id",uuid:B8()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return Y$.set(Q,$),E1($,Q),{chatId:Q,created:!0,joined:!0}}async function C8($){let Z=await w4($);if(!Z)return y4($),{chatId:null,disbanded:!1};let J=await r.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw Error(`feishu chat.delete failed code=${J.code} msg=${J.msg}`);if(Y$.delete(Z),J$.get($)===Z)y4($);return{chatId:Z,disbanded:!0}}async function b8($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await y3(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!x3(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await r.im.chat.delete({path:{chat_id:Z}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.delete failed code=${Y.code} msg=${Y.msg}`);return Y$.delete(Z),{chatId:Z,disbanded:!0}}async function zz($,Z){let J;do{let Q=await r.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.get failed code=${Q.code} msg=${Q.msg}`);for(let W of Q.data?.items??[])if(W.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await r.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.create failed code=${Y.code} msg=${Y.msg}`);return!0}async function f8($){try{let Z=await Y0(),Y=await(await u0(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return G(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return Y$.set($,Q),G(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return G(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return G(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function S3($,Z,J,Y){let Q=B8(),W=null;for(let H=0;H<G2.length;H++){if(G2[H]>0)await new Promise((X)=>setTimeout(X,G2[H]));try{let X=await r.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(X?.code&&X.code!==0)return G(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${X.code} msg=${X.msg}`),null;return X?.data?.message_id??null}catch(X){W=X,G(`feishu: send${$==="text"?"Text":"Card"} attempt ${H+1}/${G2.length} chat=${Z} failed: ${X}`)}}return G(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${G2.length} retries: ${W}`),null}async function y3($){let Z=await r.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw Error(`feishu chat.get failed code=${Z.code} msg=${Z.msg}`);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function x3($){return $===null||$==="normal"}async function N($,Z){return S3("text",$,"text",JSON.stringify({text:Z}))}async function i($,Z){return S3("card",$,"interactive",JSON.stringify(_0(Z)))}async function Q0($,Z){let J=await r.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(_0(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function C($,Z){try{let J=await Y0(),Q=await(await u0("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Q?.code!==0)return G(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return G(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function T$($,Z){if(!$)return null;try{return(await r.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return G(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function P$($,Z){if(!$||!Z)return;try{await r.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){G(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function l0($,Z){if(!$){G("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){G(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await Y0(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let W=await(await u0(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(W?.code!==0){G(`feishu: urgentApp ${$} code=${W?.code} msg=${W?.msg}`);return}let H=W.data?.invalid_user_id_list??[],X=Z.length-H.length;G(`feishu: urgentApp ${$} ok — delivered=${X}${H.length?` invalid=${H.length}`:""}`)}catch(Q){G(`feishu: urgentApp ${$} failed: ${Q}`)}}async function D2($,Z,J,Y){try{let Q=await Y0(),W=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await u0(W,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){G(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let X=Buffer.from(await H.arrayBuffer());A8(X9,{recursive:!0});let V=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,z=S4(X9,`${Date.now()}-${V}`);return D3(z,X),G(`feishu: downloaded ${J} ${z} (${X.length}B)`),z}catch(Q){G(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function Az($){return Gz.has(Jz($).toLowerCase())}async function b3($){let Z=await Y0(),J=new Blob([Uint8Array.from(await j3($))]),Y=new FormData;Y.append("image_type","message"),Y.append("image",J,c0($));let W=await(await u0("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return G(`feishu: uploadImage ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.image_key??null}async function w8($){try{let Z=P3($);if(!Z.isFile())return G(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>C3)return G(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return G(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return b3($)}async function Kz($){let Z=await Y0(),J=new Blob([Uint8Array.from(await j3($))]),Y=new FormData;Y.append("file_type","stream"),Y.append("file_name",c0($)),Y.append("file",J,c0($));let W=await(await u0("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return G(`feishu: uploadFile ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.file_key??null}async function f3($,Z){try{let J=await r.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"image",content:JSON.stringify({image_key:Z})}});if(J?.code&&J.code!==0)return G(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return G(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function w3($,Z){try{let J=await r.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"file",content:JSON.stringify({file_key:Z})}});if(J?.code&&J.code!==0)return G(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return G(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function v8($,Z){try{let Y=P3(Z);if(!Y.isFile())return await N($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>C3)return await N($,`❌ 出站文件: ${c0(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return await N($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=Az(Z);try{if(J){let Y=await b3(Z);if(!Y)return await N($,`❌ 出站图片上传失败: ${c0(Z)}`),!1;return await f3($,Y)!=null}else{let Y=await Kz(Z);if(!Y)return await N($,`❌ 出站文件上传失败: ${c0(Z)}`),!1;return await w3($,Y)!=null}}catch(Y){return G(`feishu: uploadAndSend ${Z} failed: ${Y}`),await N($,`❌ 出站文件异常: ${c0(Z)} — ${Y}`),!1}}function h8($){A8($,{recursive:!0}),G(`feishu: provisioned ${$}`);let Z=S4(G3(),".codex","config.toml");try{A8(S4(G3(),".codex"),{recursive:!0});let J="";try{J=m0(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
51
+ `:"";try{this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:J+$}]},parent_tool_use_id:null,priority:"now"})}catch(Y){let Q=Y instanceof Error?Y:Error(String(Y));A(`claude-agent-process: sendUserText failed: ${Q.message}`),this.failTurnStart(Q)}}sendInterrupt(){this.query?.interrupt().catch(($)=>A(`claude-agent-process: interrupt failed: ${$}`))}sendPermissionResponse($,Z,J){let Y=this.pendingPermissions.get(String($));if(!Y){A(`claude-agent-process: permission response for unknown request ${$}`);return}if(this.pendingPermissions.delete(String($)),Y.cleanup?.(),Z==="allow")Y.resolve({behavior:"allow",updatedInput:J?.updatedInput??{}});else Y.resolve({behavior:"deny",message:J?.denyMessage??""})}sendHookResponse($,Z={}){A("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 A(`claude-agent-process: kill failed: ${J.message}`),J}if(Z){let J=Error(`claude Agent SDK close failed: ${Z.message}`,{cause:Z});throw A(`claude-agent-process: kill failed: ${J.message}`),J}}async listModels(){if(!this.started)this.sendInitialize();if(!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");return(await this.query.supportedModels()).map(Xz)}async setModelSettings($,Z){let J=X7($);if(!a0(Z))throw Error(`invalid Claude effort: ${String(Z)}`);if(!this.started)this.sendInitialize();if(!this.query)throw Error("claude-agent-process: SDK query not initialized (sendInitialize failed or not called)");if(J)await this.query.setModel(J);if(Z==="max")await this.query.applyFlagSettings({ultracode:!0,effortLevel:null});else await this.query.applyFlagSettings({effortLevel:Z,ultracode:null});this.opts.model=$,this.opts.effort=Z,this.lastModel=J?j$($):"claude:default",this.lastEffort=Z}async compactThread(){if(!this.input)throw Error("claude thread not initialized");return this.input.push({type:"user",session_id:this.sessionId??"",message:{role:"user",content:[{type:"text",text:"/compact"}]},parent_tool_use_id:null,priority:"now"}),new Promise(($,Z)=>{let J=!1,Y=()=>{this.off("context_compacted",Q),this.off("assistant_text",W),this.off("exit",H),this.off("error",X)},Q=()=>{if(J)return;J=!0,Y(),$()},W=(V)=>{if(J)return;if((V?.text??"").includes("Not enough messages to compact"))J=!0,Y(),Z(new _2)},H=()=>{if(J)return;J=!0,Y(),Z(Error("claude thread exited during /compact"))},X=(V)=>{if(J)return;J=!0,Y(),Z(V instanceof Error?V:Error(String(V)))};this.on("context_compacted",Q),this.on("assistant_text",W),this.once("exit",H),this.once("error",X)})}canUseTool($,Z,J){if($!=="AskUserQuestion")return Promise.resolve({behavior:"allow",updatedInput:Z});let Y=_z(Z);if(Y.length===0)return A("claude-agent-process: AskUserQuestion 无有效 questions — allow 原样"),Promise.resolve({behavior:"allow",updatedInput:Z});let Q={...Z,questions:Y},W=`claude_perm_${++this.requestCounter}`,H=J.toolUseID||W,X={request_id:W,tool_name:"AskUserQuestion",input:Q,tool_use_id:H},V=new Promise((z)=>{let G=(B)=>{J.signal.removeEventListener("abort",_),z(B)},_=()=>{if(!this.pendingPermissions.delete(W))return;G({behavior:"deny",message:"aborted"})};J.signal.addEventListener("abort",_,{once:!0}),this.pendingPermissions.set(W,{kind:"dialog",resolve:G,request:X})});return this.emitToolUseOnce(H,"AskUserQuestion",Q,null),this.emit("can_use_tool",X),V}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){A(`claude-agent-process: read loop stopped after requested shutdown: ${J.message}`),this.finishExit(null,null);return}A(`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(),A(`claude-agent-process: exited code=${$} signal=${Z} expected=${this.expectedExit}`),this.emit("exit",{code:$,signal:Z,expected:this.expectedExit})}denyPendingPermissions($){for(let[Z,J]of this.pendingPermissions)J.cleanup?.(),J.resolve({behavior:"deny",message:$}),this.pendingPermissions.delete(Z)}async waitForExit($){if(!this.alive)return!0;return new Promise((Z)=>{let J=!1,Y=(W)=>{if(J)return;J=!0,clearTimeout(Q),Z(W)},Q=setTimeout(()=>Y(!this.alive),Math.max(0,$));this.exitPromise.then(()=>Y(!0))})}handleMessage($){let Z=$;if(typeof Z.session_id==="string"&&Z.session_id)this.sessionId=Z.session_id;switch(Z.type){case"system":this.handleSystemMessage(Z);return;case"assistant":this.handleAssistantMessage(Z);return;case"user":this.handleUserMessage(Z);return;case"result":this.handleResultMessage(Z);return;case"rate_limit_event":this.emit("rate_limits_updated",Z.rate_limit_info);return;case"stream_event":return;default:A(`claude-agent-process: unhandled message type=${Z.type??"unknown"} subtype=${Z.subtype??""}`)}}handleSystemMessage($){switch($.subtype){case"init":if(typeof $.model==="string"&&$.model)this.lastModel=j$($.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.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":A(`claude-agent-process: api retry attempt=${$.attempt}/${$.max_retries} status=${$.error_status} error=${$.error}`);return;case"permission_denied":A(`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){A("claude-agent-process: task_notification missing task_id");return}if($.status!=="completed"&&$.status!=="failed"&&$.status!=="stopped"){A(`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:A(`claude-agent-process: unhandled system subtype=${String($.subtype??"unknown")}`);return}}handleAssistantMessage($){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=j$(Z.model);let Y=Array.isArray(Z?.content)?Z.content:[];for(let Q of Y){if(!Q||typeof Q!=="object")continue;if(Q.type==="text"&&typeof Q.text==="string"&&Q.text.length>0){let W=Wz(Q.text);if(W){if(this.pendingServerToolInputs.push(W),this.pendingServerToolInputs.length>20)this.pendingServerToolInputs.shift()}if(Hz(Q.text))continue;let H=$.uuid??Z?.id;this.emit("assistant_text",{uuid:H,text:Q.text,parentToolUseId:J}),this.emit("assistant_block_stop",{index:H,parentToolUseId:J})}else if(Q.type==="tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Q.name,Q.input??{},J);else if(Q.type==="server_tool_use"&&typeof Q.id==="string"&&typeof Q.name==="string")this.emitToolUseOnce(Q.id,Qz(Q.name),{tool:Q.name,input:this.serverToolInput(Q.name,Q.input??{})},J);else if(Q.type==="tool_result"&&typeof Q.tool_use_id==="string")this.emitToolResultOnce(Q.tool_use_id,Yz(Q.content),Q.is_error===!0,J)}}emitToolUseOnce($,Z,J,Y){if(this.emittedToolUseIds.has($))return;this.emittedToolUseIds.add($),this.emit("tool_use",{id:$,name:Z,input:J,parentToolUseId:Y})}serverToolInput($,Z){let J=Z;if(J&&typeof J==="object"&&!Array.isArray(J)&&Object.keys(J).length>0)return J;let Y=this.pendingServerToolInputs.findIndex((Q)=>Q.name===$);if(Y>=0){let[Q]=this.pendingServerToolInputs.splice(Y,1);return Q.input}return J}emitToolResultOnce($,Z,J,Y){if(this.emittedToolResultIds.has($))return;this.emittedToolResultIds.add($),this.emit("tool_result",{tool_use_id:$,content:Z,is_error:J,parentToolUseId:Y})}handleUserMessage($){let Z=$.message?.content;if($.isMeta===!0&&$.promptSource==="sdk"&&typeof Z==="string"&&Z.trim())this.emit("scheduled_turn_input",{text:Z,promptId:typeof $.promptId==="string"&&$.promptId?$.promptId:null});let J=Array.isArray(Z)?Z:[];for(let Y of J){if(!Y||typeof Y!=="object")continue;if(Y.type!=="tool_result"||typeof Y.tool_use_id!=="string")continue;let Q=$.tool_use_result,W=R3(Y.content),H=Q&&typeof Q==="object"?[typeof Q.stdout==="string"?Q.stdout:"",typeof Q.stderr==="string"?Q.stderr:""].filter(Boolean).join(`
52
+ `):"",X=W||H;this.emitToolResultOnce(Y.tool_use_id,X,Y.is_error===!0||Q?.interrupted===!0,$.parent_tool_use_id??null)}}handleResultMessage($){if(typeof $.session_id==="string"&&$.session_id)this.sessionId=$.session_id;this.turnActive=!1;let Z=eV($.usage),J=$.modelUsage??$.model_usage,Y=Zz(J);if(!Z&&!Y.usage)A(`claude-agent-process: result usage missing rootKeys=${G7($).join(",")||"-"} usageKeys=${G7($.usage).join(",")||"-"} modelUsageKeys=${G7(J).join(",")||"-"}`);if(this.lastUsage=Z,Y.usage)this.cumulativeUsageFromResults=k4(Y.usage),this.lastTotalUsage=k4(Y.usage);else if(Z)this.cumulativeUsageFromResults=Jz(this.cumulativeUsageFromResults,Z),this.lastTotalUsage=k4(this.cumulativeUsageFromResults);else this.lastTotalUsage=this.cumulativeUsageFromResults?k4(this.cumulativeUsageFromResults):null;if(Y.contextWindow!=null){let X=K3(this.opts.model,this.tokenSourceId);if(_3.set(X,Y.contextWindow),this.tokenSourceId)for(let[V,z]of Object.entries(J??{})){let G=z?.contextWindow;if(typeof G==="number"&&G>0)H3(this.tokenSourceId,V,G)}}this.lastContextWindow=_3.get(K3(this.opts.model,this.tokenSourceId))??Y.contextWindow??null;let Q=B7(this.opts.workDir,this.sessionId??""),W=$z(Q);if(this.lastContextTokens=A3(W)??(S4(Q)?A3(Z):null),this.lastTotalUsage||this.lastUsage)this.emit("token_usage",{usage:this.lastUsage,totalUsage:this.lastTotalUsage,contextWindow:this.lastContextWindow,threadId:this.sessionId??void 0,turnId:$.uuid});let H=typeof $.subtype==="string"?$.subtype:$.is_error?"error":"success";this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:typeof $.duration_ms==="number"?$.duration_ms:null,num_turns:typeof $.num_turns==="number"?$.num_turns:1,usage:this.lastUsage,subtype:H,is_error:$.is_error===!0||H!=="success"},this.emit("result",{subtype:H,is_error:this.lastResult.is_error,...this.lastResult.is_error?{error:Array.isArray($.errors)&&$.errors.length?$.errors.map(String).join(`
53
+ `):String($.result??$.error??$.api_error_message??H)}:{},duration_ms:this.lastResult.duration_ms,usage:this.lastUsage,checkpoint:!this.lastResult.is_error&&this.lastAssistantUuid&&this.sessionId?{provider:"claude",kind:"assistant-message",id:this.lastAssistantUuid,source:{provider:"claude",sessionId:this.sessionId,cwd:this.opts.workDir}}:null})}failTurnStart($){this.turnActive=!1,this.lastAssistantUuid=null,this.lastResult={cost_usd:null,cost_delta_usd:null,duration_ms:null,num_turns:null,usage:this.lastUsage,subtype:"claude_turn_start_failed",is_error:!0},this.emit("result",{subtype:this.lastResult.subtype,is_error:!0,duration_ms:null,usage:this.lastUsage,error:$.message})}}});var U3={};B1(U3,{waitForTokenSourceModelRefresh:()=>C4,tokenSourceFactories:()=>N1,setDefaultTokenSource:()=>P7,scrubAnthropicEnv:()=>m$,resetTokenSourceRegistry:()=>j7,registerTokenSourceFactory:()=>Y$,registerTokenSource:()=>L7,refreshAllTokenSourceModels:()=>P2,pendingTokenSourceModelRefresh:()=>k1,listTokenSourcesByAgent:()=>F3,listTokenSources:()=>u$,listEnabledTokenSourcesByAgent:()=>b4,getTokenSource:()=>$0});function m$($){let Z={...$};for(let J of qz)delete Z[J];return Z}function Y$($){D3.set($.kind,$)}function N1(){return[...D3.values()]}function L7($,Z){if(L2.set($.id,$),Z?.default||x4===null)x4=$.id}function $0($){return $?L2.get($):void 0}function u$(){return[...L2.values()]}function F3($){return u$().filter((Z)=>Z.agent===$)}function b4($){return F3($).filter((Z)=>Z.enabled)}function P7($){if(L2.has($))x4=$}function j7(){L2.clear(),x4=null,M3++}function P2(){let $=M3;if(T1?.generation===$)return T1.promise;let Z=Promise.allSettled(u$().map(async(J)=>{await J.refreshModels(),A(`token-source ${J.id}: ${J.models.length} models loaded`)})).then(()=>{}).finally(()=>{if(T1?.promise===Z)T1=null});return T1={generation:$,promise:Z},Z}function k1(){return T1?.promise??null}async function C4(){let $;while($=k1())await $}var qz,D3,L2,x4=null,M3=0,T1=null;var G0=N(()=>{I();qz=["ANTHROPIC_API_KEY","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_BASE_URL","ANTHROPIC_DEFAULT_OPUS_MODEL","ANTHROPIC_DEFAULT_SONNET_MODEL","ANTHROPIC_DEFAULT_HAIKU_MODEL"];D3=new Map;L2=new Map});function w4($){let Z=$.tokenSourceId?$0($.tokenSourceId):void 0;if($.tokenSourceId&&!Z)throw Error(`token source not found: ${$.tokenSourceId}`);if(Z&&!Z.enabled)throw Error(`token source disabled: ${Z.id}`);if(Z&&Z.agent!==$.provider)throw Error(`token source ${Z.id} belongs to ${Z.agent}, not ${$.provider}`);if(Z?.modelCatalogState?.status==="failed")throw Error(`model catalog refresh failed for ${Z.id}: ${Z.modelCatalogState.error??"MISS"}`);if(Z?.modelCatalogState?.status==="idle"||Z?.modelCatalogState?.status==="loading")throw Error(`model catalog is not ready for ${Z.id}: ${Z.modelCatalogState.status}`);let J=$.model??Z?.defaultModel;if(Z&&J&&!Z.models.some((W)=>W.model===J))throw Error(`model is not present in token source ${Z.id}: ${J}`);let Y=Z&&J?Z.resolveSpawnModel(J):J;if(J&&!Y)throw Error(`model did not resolve: ${$.tokenSourceId??"default"}/${J}`);let Q=Z?(W)=>Z.spawnEnv(W):void 0;if($.provider==="claude"){if(j3(),!a0($.effort))throw Error(`invalid Claude effort: ${$.effort??"MISS"}`);return{process:new q7({workDir:$.workDir,model:Y,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}:{},...Z?{settingSources:Z.settingSources??["project","local"]}:{},...$.managedSkillPluginPath?{managedSkillPluginPath:$.managedSkillPluginPath}:{},tokenSourceId:Z?.id??null,transformEnv:Q,hostEnv:$.hostEnv}),sourceRevision:Z?.spawnRevision??null}}if($.effort!==void 0&&!S0($.effort))throw Error(`invalid Codex effort: ${$.effort}`);return{process:new M1({workDir:$.workDir,model:Y,effort:$.effort,launch:$.launch,...$.developerInstructions?{appendSystemPrompt:$.developerInstructions}:{},...$.allowDelegation===!1?{allowDelegation:!1}:{},tokenSourceId:Z?.id??null,transformEnv:Q,hostEnv:$.hostEnv,serviceName:$.serviceName}),sourceRevision:Z?.spawnRevision??null}}var R7=N(()=>{I$();y4();F1();G0()});function f4($,Z){return`http://${$==="0.0.0.0"?"127.0.0.1":$==="::"||$==="::1"?"[::1]":$}:${Z}`}async function D7($){let Z=await U7("feishu chat.get",()=>t.im.chat.get({path:{chat_id:$},params:{user_id_type:"open_id"}}));if(Z.code&&Z.code!==0)v4("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 M7($,Z){let J=await U7("feishu tasklist.create",()=>t.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)v4("feishu tasklist.create",J);let Y=J.data?.tasklist,Q=Y?.guid;if(!Q)throw Error("feishu tasklist.create returned no guid");return{guid:Q,name:Y?.name||$,url:Y?.url??"",createdAt:Y?.created_at}}async function F7($){let Z=await U7("feishu tasklist.delete",()=>t.task.v2.tasklist.delete({path:{tasklist_guid:$}}));if(Z.code&&Z.code!==0)v4("feishu tasklist.delete",Z)}function O3($,Z){let J=Z&&typeof Z==="object"?Z:{},Y=J.response?.data&&typeof J.response.data==="object"?J.response.data:J.data&&typeof J.data==="object"?J.data:J,Q=Y.code??J.code,W=Y.msg??Y.message??J.msg??J.message??"unknown error",H=Y.error?.permission_violations??Y.permission_violations??J.error?.permission_violations,X=Array.isArray(H)?H.map((V)=>V?.scope??V?.subject??V?.name??V).filter(Boolean).join(", "):"";return`${$} failed code=${Q??"unknown"} msg=${W}${X?` missing_scopes=${X}`:""}`}async function U7($,Z){try{return await Z()}catch(J){v4($,J)}}function v4($,Z){throw Error(O3($,Z))}var E3=N(()=>{s()});var Z0={};B1(Z0,{writeAliveMarker:()=>E2,urgentApp:()=>n$,uploadImageKey:()=>Nz,uploadAndSend:()=>o7,updateCard:()=>r0,unbindSessionChat:()=>I4,tempProjectName:()=>o0,tempChatName:()=>h7,setPendingConversationLaunchChecked:()=>R$,sendTextRaw:()=>C,sendText:()=>T,sendImage:()=>r3,sendFile:()=>t3,sendCard:()=>i,sanitizeSessionName:()=>t7,resolveProjectDir:()=>u4,replaceTurnAnchors:()=>m0,registerTempSessionLease:()=>y7,refreshChatList:()=>T2,readAliveMarker:()=>p7,provisionProject:()=>r7,projectProfile:()=>y1,preferredChatForSession:()=>Y0,loadTempSessionLeases:()=>S7,loadSessionTurnsMap:()=>f7,loadSessionResumeMap:()=>C7,loadSessionModelMap:()=>g7,loadSessionChatMap:()=>b7,listNormalChatIdsByName:()=>l4,isOpenAIChatGPTAuthenticated:()=>k2,hasTempSessionLease:()=>x7,getTurnAnchors:()=>F2,getTenantToken:()=>Q$,getSessionResumeRef:()=>d$,getSessionModelSelection:()=>m7,getSessionBranchBase:()=>U2,getPendingConversationLaunch:()=>O2,formatFeishuApiError:()=>O3,findNormalChatIdByName:()=>i4,fetchChatOwnerOpenId:()=>D7,fetchChatName:()=>a7,ensureChatForSession:()=>l7,downloadAttachment:()=>N2,disbandChatForSessionExact:()=>n7,disbandChatForSession:()=>d7,deleteTasklistByGuid:()=>F7,deleteReaction:()=>j0,createTempChatForSession:()=>i7,createTasklistWithOwner:()=>M7,client:()=>t,clearSessionResumeChecked:()=>x1,clearSessionConversationState:()=>u7,chatNameCache:()=>Q0,chatIdForSession:()=>p4,bindSessionToChat:()=>S1,bindSessionResumeChecked:()=>M2,bindSessionModelChecked:()=>c7,bindSessionModel:()=>I7,appendTurnAnchorChecked:()=>v7,addReaction:()=>T0,PROJECTS_ROOT:()=>c3});import*as b3 from"@larksuiteoapi/node-sdk";import{execSync as C3}from"node:child_process";import{randomUUID as k7}from"node:crypto";import{existsSync as Lz,mkdirSync as E7,readFileSync as l$,statSync as w3,writeFileSync as f3}from"node:fs";import{readFile as v3}from"node:fs/promises";import{homedir as T3}from"node:os";import{basename as p$,extname as Pz,isAbsolute as h3,join as g4}from"node:path";function T7(){let $={};for(let[Z,J]of E0)$[Z]=J;H0(D6,$)}function S7(){E0.clear();try{let $=JSON.parse(l$(D6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("lease file must contain an object");for(let[Z,J]of Object.entries($)){let Y=J;if(typeof Z!=="string"||!Z||Y.chatId!==Z||typeof Y.sessionName!=="string"||!o0(Y.sessionName)||typeof Y.createdAt!=="number"||!Number.isFinite(Y.createdAt)){A(`feishu: rejected malformed temp-session lease chat=${Z}`);continue}E0.set(Z,{chatId:Z,sessionName:Y.sessionName,createdAt:Y.createdAt})}A(`feishu: loaded ${E0.size} temporary-session leases`)}catch($){if($?.code!=="ENOENT")A(`feishu: load temp-session leases failed: ${$?.message??$}`)}}function y7($,Z){if(!o0($))throw Error(`refusing to lease non-temporary session name "${$}"`);if(!Z)throw Error("cannot lease a temporary session without chat_id");for(let Q of E0.values())if(Q.sessionName===$&&Q.chatId!==Z)throw Error(`temporary session name "${$}" is already leased to ${Q.chatId}`);let J=E0.get(Z),Y={sessionName:$,chatId:Z,createdAt:Date.now()};E0.set(Z,Y);try{T7()}catch(Q){if(J)E0.set(Z,J);else E0.delete(Z);throw Q}}function x7($,Z){let J=E0.get(Z);return J?.sessionName===$&&J.chatId===Z}function y1($){return v.projects[$]}function u4($){return y1($)?.cwd?.trim()||g4(c3,$)}function i$($,Z={}){return fetch($,{...Z,signal:Z.signal??AbortSignal.timeout(jz)})}async function Q$(){if(h4&&Date.now()<N3)return h4;return O7??=(async()=>{let $=await i$("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({app_id:g3,app_secret:I3})}),Z=await $.json();if(!$.ok||!Z.tenant_access_token)throw Error(`feishu: tenant token failed HTTP ${$.status} code=${Z.code??"MISS"} msg=${Z.msg??"MISS"}`);return h4=Z.tenant_access_token,N3=Date.now()+Math.max(0,(Z.expire??7200)-60)*1000,h4})().finally(()=>{O7=null}),O7}function b7(){try{let $=JSON.parse(l$(L6,"utf8"));for(let[Z,J]of Object.entries($))if(typeof J==="string")Y0.set(Z,J);A(`feishu: loaded ${Y0.size} session→chat bindings`)}catch($){if($?.code!=="ENOENT")A(`feishu: load session-chat-map failed: ${$?.message??$}`)}}function m3(){try{N7()}catch($){A(`feishu: save session-chat-map failed: ${$}`)}}function N7(){let $={};for(let[Z,J]of Y0)$[Z]=J;H0(L6,$)}function S1($,Z){if(Y0.get($)===Z)return;let J=Y0.get($);Y0.set($,Z),m3(),A(`feishu: bound session "${$}" → ${Z}${J?` (was ${J})`:""}`)}function I4($){let Z=Y0.get($);if(!Z)return;Y0.delete($),m3(),A(`feishu: unbound session "${$}" from ${Z}`)}function R2($,Z){let J=J0.get($)??{};J[Z.provider]=Z,J0.set($,J)}function k3($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let J=$,Y=J.provider==="claude"||J.provider==="codex"?J.provider:Z??null;if(!Y||Z&&Y!==Z)return null;let Q=typeof J.sessionId==="string"?J.sessionId.trim():typeof J.session_id==="string"?J.session_id.trim():"";if(!Q)return null;if(J.cwd===void 0||J.cwd===null)return{provider:Y,sessionId:Q,cwd:null};if(typeof J.cwd!=="string"||!h3(J.cwd))return null;return{provider:Y,sessionId:Q,cwd:J.cwd}}function S3($){let Z=$.sessionId.trim();if(!Z)throw Error("cannot bind an empty conversation session id");if($.provider!=="codex"&&$.provider!=="claude")throw Error(`cannot bind an unknown conversation provider: ${String($.provider)}`);if(typeof $.cwd!=="string"||!h3($.cwd))throw Error(`cannot bind a conversation without an absolute cwd: ${String($.cwd)}`);return{provider:$.provider,sessionId:Z,cwd:$.cwd}}function Rz($,Z,J){if(typeof $!=="string")return S3($);if(!Z)throw Error("cannot bind a conversation without a provider");return S3({provider:Z,sessionId:$,cwd:J??null})}function C7(){try{let $=JSON.parse(l$(P6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("resume map must contain an object");J0.clear();for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){R2(Z,{provider:"codex",sessionId:J.trim(),cwd:null});continue}if(!J||typeof J!=="object"||Array.isArray(J))continue;let Y=J,Q=k3(Y);if(Q){R2(Z,Q);continue}for(let W of["codex","claude"]){let H=Y[W];if(typeof H==="string"&&H.trim()){R2(Z,{provider:W,sessionId:H.trim(),cwd:null});continue}let X=k3(H,W);if(X)R2(Z,X)}}A(`feishu: loaded ${J0.size} session→resume bindings`)}catch($){if($?.code!=="ENOENT")A(`feishu: load session-resume-map failed: ${$?.message??$}`)}}function c4(){let $={};for(let[Z,J]of J0){let Y={};if(J.codex)Y.codex={...J.codex};if(J.claude)Y.claude={...J.claude};$[Z]=Y}H0(P6,$)}function M2($,Z,J,Y){let Q=Rz(Z,J,Y),W=J0.get($),H=W?{...W}:void 0,X=W?.[Q.provider];if(X?.sessionId===Q.sessionId&&X.cwd===Q.cwd)return;R2($,Q);try{c4()}catch(V){if(H)J0.set($,H);else J0.delete($);throw V}}function d$($,Z="codex"){let J=J0.get($)?.[Z];return J?{...J}:null}function x1($,Z){let J=J0.get($);if(!J||Z&&J[Z]===void 0)return;let Y={...J};if(!Z)J0.delete($);else{let Q={...J};if(delete Q[Z],!Q.codex&&!Q.claude)J0.delete($);else J0.set($,Q)}try{c4()}catch(Q){throw J0.set($,Y),Q}}function u3($){if(!$||typeof $!=="object")return null;let Z=$;if(Z.provider!=="claude"&&Z.provider!=="codex")return null;let J=typeof Z.sessionId==="string"?Z.sessionId.trim():"";if(!J)return null;let Y;if(Z.cwd===void 0||Z.cwd===null)Y=null;else if(typeof Z.cwd==="string"&&Z.cwd.trim())Y=Z.cwd;else return null;return{provider:Z.provider,sessionId:J,cwd:Y}}function p3($){if(!$||typeof $!=="object")return null;let Z=$,J=Z.source;if(!J||typeof J!=="object")return null;let Y=u3(J),Q=typeof Z.id==="string"?Z.id.trim():"";if(!Q||!Y)return null;if(Z.provider==="claude"&&Z.kind==="assistant-message"&&Y.provider==="claude")return{provider:"claude",kind:"assistant-message",id:Q,source:{...Y,provider:"claude"}};if(Z.provider==="codex"&&Z.kind==="turn"&&Y.provider==="codex")return{provider:"codex",kind:"turn",id:Q,source:{...Y,provider:"codex"}};return null}function l3($){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=u3(Z.source);if(!J)return null;let Y=Z.kind==="resume"?{kind:"resume",source:J}:(()=>{if(!Object.prototype.hasOwnProperty.call(Z,"through"))return{kind:"fork",source:J};let Q=p3(Z.through);return Q?{kind:"fork",source:J,through:Q}:null})();if(!Y)return null;try{z0(Y,J.provider)}catch{return null}return Y}function Dz($){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 Mz($,Z){if(!$||typeof $!=="object")return null;let J=$;if(typeof J.ts!=="number"||!Number.isFinite(J.ts))return null;let Y=Object.prototype.hasOwnProperty.call(J,"checkpoint"),Q=p3(J.checkpoint);if(Y&&!Q)return null;if(!Q){if(Z!=="claude")return null;let W=typeof J.uuid==="string"?J.uuid.trim():"",H=typeof J.sid==="string"?J.sid.trim():"";if(!W||!H)return null;Q={provider:"claude",kind:"assistant-message",id:W,source:{provider:"claude",sessionId:H,cwd:null}}}return{checkpoint:Q,preview:String(J.preview??""),ts:J.ts,writes:Dz(J.writes)}}function Fz($){if(!$||typeof $!=="object")return null;let Z=$,J=l3(Z.launch);if(J?.kind!=="fork"||J.source.provider!=="claude"||J.source.cwd===null)return null;let Y=Z.previousSessionId,Q=Y===null?null:typeof Y==="string"&&Y.trim()?Y.trim():void 0;if(Q===void 0)return null;return{launch:{...J,source:{...J.source,provider:"claude"}},previousSessionId:Q}}function w7($){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 f7(){try{let $=JSON.parse(l$(j6,"utf8"));if(!$||typeof $!=="object"||Array.isArray($))throw Error("turns map must contain an object");l.clear();let Z=0,J=0;for(let[Y,Q]of Object.entries($)){let W,H,X=null;if(Array.isArray(Q))W=Q,H=null;else if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let _=Q;if(!Array.isArray(_.anchors)||!Object.prototype.hasOwnProperty.call(_,"base")){J++;continue}if(W=_.anchors,_.base===null)H=null;else{let B=l3(_.base);if(!B){J++;continue}H=B}if(Object.prototype.hasOwnProperty.call(_,"pendingLaunch")){let B=Fz(_.pendingLaunch);if(!B){J++;continue}X=B}}else{J++;continue}let V=J0.get(Y),z=V?.claude!==void 0&&V.codex===void 0?"claude":null,G=[];for(let _ of W){let B=Mz(_,z);if(B)G.push(B);else J++}if(G.length||H!==null||X)l.set(Y,{base:H,anchors:G,...X?{pendingLaunch:X}:{}}),Z+=G.length}if(A(`feishu: loaded ${Z} turn anchors across ${l.size} sessions`),J>0)A(`feishu: rejected ${J} malformed turn anchors while loading`)}catch($){if($?.code!=="ENOENT")A(`feishu: load session-turns-map failed: ${$?.message??$}`)}}function D2(){let $={};for(let[Z,J]of l)$[Z]=J;H0(j6,$)}function v7($,Z){let J=l.get($),Y=[...J?.anchors??[],Z],Q=J?.base??null;if(Y.length>y3){let W=Y.splice(0,Y.length-y3),H=W[W.length-1].checkpoint;Q={kind:"fork",source:H.source,through:H}}l.set($,{base:Q,anchors:Y,...J?.pendingLaunch?{pendingLaunch:J.pendingLaunch}:{}});try{D2()}catch(W){if(J)l.set($,J);else l.delete($);throw W}}function F2($){return l.get($)?.anchors??[]}function U2($){return l.get($)?.base??null}function O2($){let Z=l.get($)?.pendingLaunch;return Z?w7(Z):null}function R$($,Z){if(Z){if(Z.launch.source.cwd===null)throw Error("pending conversation launch source cwd is missing");z0(Z.launch,"claude",Z.launch.source.cwd)}let J=l.get($),Y=J?.base??null,Q=J?.anchors.slice()??[];if(!Z&&Q.length===0&&Y===null)l.delete($);else l.set($,{base:Y,anchors:Q,...Z?{pendingLaunch:w7(Z)}:{}});try{D2()}catch(W){if(J)l.set($,J);else l.delete($);throw W}}function m0($,Z,J,Y){let Q=l.get($),W=Y===void 0?Q?.pendingLaunch:Y??void 0,H=W?w7(W):void 0;if(Z.length===0&&J===null&&!H)l.delete($);else l.set($,{base:J,anchors:Z.slice(),...H?{pendingLaunch:H}:{}});try{D2()}catch(X){if(Q)l.set($,Q);else l.delete($);throw X}}function o0($){return x3.test($)?$.replace(x3,""):null}function h7($,Z=[]){let J=new Date,Y=(X)=>String(X).padStart(2,"0"),Q=`${Y(J.getMonth()+1)}${Y(J.getDate())}-${Y(J.getHours())}${Y(J.getMinutes())}`,W=new Set([...Q0.values(),...l.keys(),...Z]),H=`${$}*${Q}`;for(let X=2;W.has(H);X++)H=`${$}*${Q}-${X}`;return H}function g7(){try{let $=JSON.parse(l$(R6,"utf8"));for(let[Z,J]of Object.entries($)){if(typeof J==="string"&&J.trim()){P0.set(Z,{provider:O1(J),model:J,effort:null});continue}if(!J||typeof J!=="object")continue;let{model:Y,provider:Q}=J,W=Q==="claude"||Q==="codex"?Q:typeof Y==="string"&&Y.trim()?O1(Y):"claude",H=typeof Y==="string"&&Y.trim()?Y:null;if(W==="claude"&&!H)continue;let{effort:X,tokenSourceId:V}=J,z=typeof V==="string"&&V.trim()?V.trim():null,G=W==="claude"?a0(X)?X:null:S0(X)?X:null;P0.set(Z,{provider:W,model:H,effort:G,...z?{tokenSourceId:z}:{}})}A(`feishu: loaded ${P0.size} session→model bindings`)}catch($){if($?.code!=="ENOENT")A(`feishu: load session-model-map failed: ${$?.message??$}`)}}function Uz(){try{m4()}catch($){A(`feishu: save session-model-map failed: ${$}`)}}function m4(){let $={};for(let[Z,J]of P0)$[Z]=J;H0(R6,$)}function I7($,Z,J,Y,Q){let W=P0.get($);if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;P0.set($,{provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}}),Uz()}function c7($,Z,J,Y,Q){let W=P0.get($),H={provider:Z,model:J,effort:Y,...Q?{tokenSourceId:Q}:{}};if(W?.provider===Z&&W.model===J&&W.effort===Y&&(W.tokenSourceId??null)===(Q??null))return;P0.set($,H);try{m4()}catch(X){if(W)P0.set($,W);else P0.delete($);throw X}}function m7($){let Z=P0.get($);if(Z)return Z;let J=o0($);return J?P0.get(J)??null:null}function u7($){let Z=Y0.get($),J=J0.get($),Y=P0.get($),Q=l.get($),W=[...E0.entries()].filter(([,H])=>H.sessionName===$);Y0.delete($),J0.delete($),P0.delete($),l.delete($);for(let[H]of W)E0.delete(H);try{N7(),c4(),m4(),D2(),T7()}catch(H){if(Z)Y0.set($,Z);if(J)J0.set($,J);if(Y)P0.set($,Y);if(Q)l.set($,Q);for(let[V,z]of W)E0.set(V,z);let X=[H];for(let V of[N7,c4,m4,D2,T7])try{V()}catch(z){X.push(z)}throw X.length===1?X[0]:AggregateError(X,`failed to clear and restore conversation state for ${$}`)}}function E2($){try{H0(H4,$)}catch(Z){A(`feishu: write alive marker failed: ${Z}`)}}function p7(){if(!Lz(H4))return[];try{let $=l$(H4,"utf8"),Z=JSON.parse($);return Array.isArray(Z)?Z.filter((J)=>typeof J==="string"):[]}catch($){return A(`feishu: read alive marker failed: ${$}`),[]}}function p4($){let Z=Y0.get($);if(Z){let Y=Q0.get(Z);if(Y&&Y!==$)A(`feishu: chatIdForSession("${$}"): persisted binding ${Z} has cached name "${Y}", using persisted binding`);return Z}let J=[];for(let[Y,Q]of Q0)if(Q===$)J.push(Y);if(J.length===1)return J[0];if(J.length>1)A(`feishu: chatIdForSession("${$}"): ${J.length} candidates with no binding — [${J.join(", ")}]`);return null}async function T2(){try{let $;do{let Z=await t.im.chat.list({params:{page_size:100,...$?{page_token:$}:{}}});for(let J of Z.data?.items??[])if(J.chat_id&&J.name)Q0.set(J.chat_id,J.name);$=Z.data?.page_token}while($);A(`feishu: refreshed chat list — ${Q0.size} groups`)}catch($){A(`feishu: refresh chat list failed: ${$}`)}}async function l4(){let $=new Map,Z;do{let J=await t.im.chat.list({params:{page_size:100,...Z?{page_token:Z}:{}}});if(J.code&&J.code!==0)throw Error(`feishu chat.list failed code=${J.code} msg=${J.msg}`);for(let Y of J.data?.items??[]){if(!Y.chat_id||!Y.name)continue;if(Y.chat_status&&Y.chat_status!=="normal")continue;Q0.set(Y.chat_id,Y.name);let Q=$.get(Y.name)??[];Q.push(Y.chat_id),$.set(Y.name,Q)}Z=J.data?.page_token}while(Z);return $}async function i4($){let Z=Y0.get($);if(Z&&Q0.get(Z)===$){let W=await d3(Z);if(W.name===$&&n3(W.status))return Z;Q0.delete(Z),I4($)}let Y=(await l4()).get($)??[];if(Y.length===0)return null;let Q=Y0.get($);if(Q&&Y.includes(Q))return Q;if(Y.length===1)return Y[0];throw Error(`multiple Feishu groups named "${$}": ${Y.join(", ")}`)}async function l7($,Z){if(!Z)throw Error("missing sender open_id; cannot add user to worktree group");let J=await i4($);if(J){let W=await Oz(J,Z);return S1($,J),{chatId:J,created:!1,joined:W}}let Y=await t.im.chat.create({params:{user_id_type:"open_id",uuid:k7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return Q0.set(Q,$),S1($,Q),{chatId:Q,created:!0,joined:!0}}async function i7($,Z){if(!Z)throw Error("missing sender open_id; cannot create temporary group");if(await i4($))throw Error(`temporary group name already exists: ${$}`);let Y=await t.im.chat.create({params:{user_id_type:"open_id",uuid:k7()},data:{name:$,user_id_list:[Z],group_message_type:"chat"}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.create failed code=${Y.code} msg=${Y.msg}`);let Q=Y.data?.chat_id;if(!Q)throw Error("feishu chat.create returned no chat_id");return Q0.set(Q,$),S1($,Q),{chatId:Q,created:!0,joined:!0}}async function d7($){let Z=await i4($);if(!Z)return I4($),{chatId:null,disbanded:!1};let J=await t.im.chat.delete({path:{chat_id:Z}});if(J.code&&J.code!==0)throw Error(`feishu chat.delete failed code=${J.code} msg=${J.msg}`);if(Q0.delete(Z),Y0.get($)===Z)I4($);return{chatId:Z,disbanded:!0}}async function n7($,Z){if(!Z)throw Error("cannot disband a temporary session without an exact chat_id");let J=await d3(Z);if(J.name!==$)throw Error(`refusing to delete chat ${Z}: expected name "${$}", got "${J.name??""}"`);if(!n3(J.status))throw Error(`refusing to delete chat ${Z}: status=${J.status??"unknown"}`);let Y=await t.im.chat.delete({path:{chat_id:Z}});if(Y.code&&Y.code!==0)throw Error(`feishu chat.delete failed code=${Y.code} msg=${Y.msg}`);return Q0.delete(Z),{chatId:Z,disbanded:!0}}async function Oz($,Z){let J;do{let Q=await t.im.chatMembers.get({path:{chat_id:$},params:{member_id_type:"open_id",page_size:100,...J?{page_token:J}:{}}});if(Q.code&&Q.code!==0)throw Error(`feishu chatMembers.get failed code=${Q.code} msg=${Q.msg}`);for(let W of Q.data?.items??[])if(W.member_id===Z)return!1;J=Q.data?.page_token}while(J);let Y=await t.im.chatMembers.create({path:{chat_id:$},params:{member_id_type:"open_id"},data:{id_list:[Z]}});if(Y.code&&Y.code!==0)throw Error(`feishu chatMembers.create failed code=${Y.code} msg=${Y.msg}`);return!0}async function a7($){try{let Z=await Q$(),Y=await(await i$(`https://open.feishu.cn/open-apis/im/v1/chats/${encodeURIComponent($)}`,{headers:{Authorization:`Bearer ${Z}`}})).json();if(Y?.code!==0)return A(`feishu: fetchChatName ${$} code=${Y?.code} msg=${Y?.msg}`),null;let Q=Y.data?.name;if(typeof Q==="string"&&Q)return Q0.set($,Q),A(`feishu: fetchChatName ${$} → "${Q}" (point lookup)`),Q;return A(`feishu: fetchChatName ${$} — chat has no name (unnamed group?)`),null}catch(Z){return A(`feishu: fetchChatName ${$} failed: ${Z}`),null}}async function i3($,Z,J,Y){let Q=k7(),W=null;for(let H=0;H<j2.length;H++){if(j2[H]>0)await new Promise((X)=>setTimeout(X,j2[H]));try{let X=await t.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:Z,msg_type:J,content:Y,uuid:Q}});if(X?.code&&X.code!==0)return A(`feishu: send${$==="text"?"Text":"Card"} rejected chat=${Z} code=${X.code} msg=${X.msg}`),null;return X?.data?.message_id??null}catch(X){W=X,A(`feishu: send${$==="text"?"Text":"Card"} attempt ${H+1}/${j2.length} chat=${Z} failed: ${X}`)}}return A(`feishu: send${$==="text"?"Text":"Card"} chat=${Z} EXHAUSTED ${j2.length} retries: ${W}`),null}async function d3($){let Z=await t.im.chat.get({path:{chat_id:$}});if(Z.code&&Z.code!==0)throw Error(`feishu chat.get failed code=${Z.code} msg=${Z.msg}`);return{name:Z.data?.name??null,status:Z.data?.chat_status??null}}function n3($){return $===null||$==="normal"}async function T($,Z){return i3("text",$,"text",JSON.stringify({text:Z}))}async function i($,Z){return i3("card",$,"interactive",JSON.stringify(q$(Z)))}async function r0($,Z){let J=await t.im.v1.message.patch({path:{message_id:$},data:{content:JSON.stringify(q$(Z))}});if(J?.code&&J.code!==0)throw Error(`feishu message.patch failed code=${J.code} msg=${J.msg}`)}async function C($,Z){try{let J=await Q$(),Q=await(await i$("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=chat_id",{method:"POST",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({receive_id:$,msg_type:"text",content:JSON.stringify({text:Z})})})).json();if(Q?.code!==0)return A(`feishu: sendTextRaw rejected chat=${$} code=${Q?.code} msg=${Q?.msg}`),null;return Q.data?.message_id??null}catch(J){return A(`feishu: sendTextRaw chat=${$} failed: ${J}`),null}}async function T0($,Z){if(!$)return null;try{return(await t.im.messageReaction.create({path:{message_id:$},data:{reaction_type:{emoji_type:Z}}}))?.data?.reaction_id??null}catch(J){return A(`feishu: addReaction ${Z} on ${$} failed: ${J}`),null}}async function j0($,Z){if(!$||!Z)return;try{await t.im.messageReaction.delete({path:{message_id:$,reaction_id:Z}})}catch(J){A(`feishu: deleteReaction ${Z} on ${$} failed: ${J}`)}}async function n$($,Z){if(!$){A("feishu: urgentApp skip — missing messageId");return}if(Z.length===0){A(`feishu: urgentApp skip — empty openIds (msg=${$})`);return}let J=await Q$(),Y=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/urgent_app?user_id_type=open_id`;try{let W=await(await i$(Y,{method:"PATCH",headers:{Authorization:`Bearer ${J}`,"Content-Type":"application/json"},body:JSON.stringify({user_id_list:Z})})).json();if(W?.code!==0){A(`feishu: urgentApp ${$} code=${W?.code} msg=${W?.msg}`);return}let H=W.data?.invalid_user_id_list??[],X=Z.length-H.length;A(`feishu: urgentApp ${$} ok — delivered=${X}${H.length?` invalid=${H.length}`:""}`)}catch(Q){A(`feishu: urgentApp ${$} failed: ${Q}`)}}async function N2($,Z,J,Y){try{let Q=await Q$(),W=`https://open.feishu.cn/open-apis/im/v1/messages/${$}/resources/${Z}?type=${J}`,H=await i$(W,{headers:{Authorization:`Bearer ${Q}`}});if(!H.ok){A(`feishu: download ${J} HTTP ${H.status}: ${(await H.text()).slice(0,200)}`);return}let X=Buffer.from(await H.arrayBuffer());E7(M6,{recursive:!0});let V=Y?Y.replace(/[^a-zA-Z0-9._-]/g,"_"):`${Z.replace(/[^a-zA-Z0-9_-]/g,"_")}.png`,z=g4(M6,`${Date.now()}-${V}`);return f3(z,X),A(`feishu: downloaded ${J} ${z} (${X.length}B)`),z}catch(Q){A(`feishu: download ${J} failed: ${Q instanceof Error?Q.message:Q}`);return}}function Tz($){return Ez.has(Pz($).toLowerCase())}async function o3($){let Z=await Q$(),J=new Blob([Uint8Array.from(await v3($))]),Y=new FormData;Y.append("image_type","message"),Y.append("image",J,p$($));let W=await(await i$("https://open.feishu.cn/open-apis/im/v1/images",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return A(`feishu: uploadImage ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.image_key??null}async function Nz($){try{let Z=w3($);if(!Z.isFile())return A(`feishu: uploadImageKey not a file — ${$}`),null;if(Z.size>a3)return A(`feishu: uploadImageKey oversize — ${$} (${(Z.size/1024/1024).toFixed(1)} MB)`),null}catch(Z){return A(`feishu: uploadImageKey stat failed — ${$}: ${Z}`),null}return o3($)}async function kz($){let Z=await Q$(),J=new Blob([Uint8Array.from(await v3($))]),Y=new FormData;Y.append("file_type","stream"),Y.append("file_name",p$($)),Y.append("file",J,p$($));let W=await(await i$("https://open.feishu.cn/open-apis/im/v1/files",{method:"POST",headers:{Authorization:`Bearer ${Z}`},body:Y})).json();if(W?.code!==0)return A(`feishu: uploadFile ${$} code=${W.code} msg=${W.msg}`),null;return W.data?.file_key??null}async function r3($,Z){try{let J=await t.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"image",content:JSON.stringify({image_key:Z})}});if(J?.code&&J.code!==0)return A(`feishu: sendImage rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return A(`feishu: sendImage failed chat=${$}: ${J}`),null}}async function t3($,Z){try{let J=await t.im.message.create({params:{receive_id_type:"chat_id"},data:{receive_id:$,msg_type:"file",content:JSON.stringify({file_key:Z})}});if(J?.code&&J.code!==0)return A(`feishu: sendFile rejected chat=${$} code=${J.code} msg=${J.msg}`),null;return J?.data?.message_id??null}catch(J){return A(`feishu: sendFile failed chat=${$}: ${J}`),null}}async function o7($,Z){try{let Y=w3(Z);if(!Y.isFile())return await T($,`❌ 出站文件: 路径不是文件 — ${Z}`),!1;if(Y.size>a3)return await T($,`❌ 出站文件: ${p$(Z)} 超过 30 MB (${(Y.size/1024/1024).toFixed(1)} MB)`),!1}catch(Y){return await T($,`❌ 出站文件: 无法读取 ${Z} (${Y})`),!1}let J=Tz(Z);try{if(J){let Y=await o3(Z);if(!Y)return await T($,`❌ 出站图片上传失败: ${p$(Z)}`),!1;return await r3($,Y)!=null}else{let Y=await kz(Z);if(!Y)return await T($,`❌ 出站文件上传失败: ${p$(Z)}`),!1;return await t3($,Y)!=null}}catch(Y){return A(`feishu: uploadAndSend ${Z} failed: ${Y}`),await T($,`❌ 出站文件异常: ${p$(Z)} — ${Y}`),!1}}function r7($){E7($,{recursive:!0}),A(`feishu: provisioned ${$}`);let Z=g4(T3(),".codex","config.toml");try{E7(g4(T3(),".codex"),{recursive:!0});let J="";try{J=l$(Z,"utf8")}catch{}let Y=`[projects.${JSON.stringify($)}]`;if(!J.includes(Y)){let Q=J.trimEnd();J=`${Q}${Q?`
54
54
 
55
55
  `:""}${Y}
56
56
  trust_level = "trusted"
57
- `,D3(Z,J)}}catch(J){G(`feishu: codex trust write failed for ${$}: ${J}`)}try{L3("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function j2(){try{let $=L3(`"${Z2()}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test($)}catch{return!1}}function M2($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var F3,U3,O3,E$,r,Yz=15000,k4="",A3=0,G8=null,Y$,J$,Z$,l,B3=200,q3,L$,G2,C3=31457280,Gz;var o=S(()=>{U$();P1();v0();R$();g();g$();S$();R1();z3();F3=v.feishu.app_id,U3=v.feishu.app_secret,O3=v.runtime.projects_root,E$=new Map;r=new R3.Client({appId:F3,appSecret:U3,disableTokenCache:!1});Y$=new Map,J$=new Map;Z$=new Map;l=new Map;q3=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;L$=new Map;G2=[0,1000,4000];Gz=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as v3}from"node:crypto";function g8($,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 h3($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function P0($){let Z=m$.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function W0($){return!m$.has($)}function u$($,Z,J){m$.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,failedReplacements:new Set,onFailure:J,closing:!1})}function I8($){return m$.get($)?.elementCount??0}function g3($){let Z=m$.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function y1($,Z){return m$.get($)?.deadElements.has(Z)??!1}function I3($,Z){let J=m$.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function v4($){let Z=P0($);return Z.sequence+=1,Z.sequence}function c3($,Z){$.deadElements.add(Z)}function m3($){return v3("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function Lz($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==M.footer)Y.push(J);return v3("sha256").update(Y.sort().join(`
58
- `)).digest("hex")}async function S1($,Z,J){let Y=await Y0(),Q=await fetch(`${_z}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(Bz)}),W=await Q.json();if(!Q.ok||W?.code!==0){let H=typeof W?.code==="number"?W.code:Q.status,X=Q.headers.get("x-tt-logid")??Q.headers.get("x-request-id")??Q.headers.get("request-id")??void 0,V=Error(`cardkit ${$} ${Z}: HTTP ${Q.status} code=${String(W?.code??"MISS")} msg=${W?.msg??"MISS"}${X?` log_id=${X}`:""}`);throw V.code=H,V.httpStatus=Q.status,V.logId=X,V}return W?.data}function Pz($){return new Promise((Z)=>setTimeout(Z,$))}function Dz($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function jz($){let Z=v4($);await S1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function c8($,Z,J,Y,Q=!1,W={}){let H=(X)=>{let V=typeof X==="object"&&X!==null?X:null,z={cardId:$,operation:Z,elementId:W.elementId,targetElementId:W.targetElementId,code:V?.code,httpStatus:V?.httpStatus,logId:V?.logId,message:X instanceof Error?X.message:String(X)};if(g8(z.code,z))z.capacityFingerprint=Lz(P0($),W.elementId,W.contentFingerprint);try{if(!Q)P0($).onFailure?.(z.code,z)}catch(A){G(`cardkit failure callback ${$}: ${A}`)}try{Y?.(z)}catch(A){G(`cardkit per-call failure callback ${$}: ${A}`)}};try{await J();return}catch(X){if(!Dz(X)){G(`cardkit ${Z} ${$}: ${X}`),H(X);return}G(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await jz($)}catch(X){G(`cardkit STREAMING_REOPEN_FAILED ${$}: ${X}`),H(X);return}try{await J()}catch(X){G(`cardkit ${Z} ${$} retry-after-reopen: ${X}`),H(X)}}function Mz($){return typeof $==="object"&&$!==null&&$.code===200740}async function o$($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:qz,Y=null;for(let Q=0;Q<J.length;Q++){let W=J[Q]??0;if(W>0)await Pz(W);try{let H=await S1("POST","/cards/id_convert",{message_id:$});if(typeof H?.card_id!=="string"||!H.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return H.card_id}catch(H){if(Y=H,!Mz(H)||Q===J.length-1)throw H;let X=J[Q+1]??0;G(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${X}ms`)}}throw Y}async function x$($){let Z=m$.get($);if(!Z)return;await Z.queue}function X$($,Z,J={},Y){if(W0($))return Promise.resolve();let Q=P0($);if(Q.closing)return Promise.resolve();let W=_0(Z),H=W.element_id,X=m3(W),V=()=>{if(!H)return;c3(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>c8($,"addElement",async()=>{let z=v4($);if(await S1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([W]),sequence:z}),Q.elementCount+=1,H!==M.footer)Q.contentFingerprints.set(H??`#${z}`,X);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(z)=>{V(),Y?.(z.code,z)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:X})),Q.queue}function n($,Z,J,Y,Q=!0){if(W0($))return Promise.resolve();let W=P0($);if(W.closing)return Promise.resolve();let H=_0(J),X=m3(H),V=()=>{c3(W,Z),W.failedReplacements.add(Z)};return W.queue=W.queue.then(()=>c8($,`replaceElement ${Z}`,async()=>{let z=W.failedAdds.get(Z);if(W.deadElements.has(Z)&&!z&&!W.failedReplacements.has(Z))return;let A=v4($);if(z)await S1("POST",`/cards/${$}/elements`,{type:z.type??"append",...z.targetElementId?{target_element_id:z.targetElementId}:{},elements:JSON.stringify([H]),sequence:A}),W.elementCount++;else await S1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:A});if(W.deadElements.delete(Z),W.failedAdds.delete(Z),W.failedReplacements.delete(Z),Z!==M.footer)W.contentFingerprints.set(Z,X)},(z)=>{if(Q)V();Y?.(z.code,z)},!Q,{elementId:Z,contentFingerprint:X})),W.queue}async function D$($,Z,J,Y={}){if(W0($))return!1;let Q=P0($);if(Q.closing)return!1;let W=!1;return await n($,Z,J,()=>{W=!0},Y.notifyCardFailure!==!1),!W&&!Q.deadElements.has(Z)}async function D0($,Z,J={}){return(await h4($,Z,J)).landed}async function h4($,Z,J={}){if(W0($))return{landed:!1};let Y=P0($);if(Y.closing)return{landed:!1};let Q=Z.element_id,W;return await X$($,Z,J,(H,X)=>{W=X}),{landed:!W&&!(Q&&Y.deadElements.has(Q)),...W?{failure:W}:{}}}function H0($,Z){if(W0($)||m$.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=i0.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},i0.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=i0.get($);if(!Q)return;if(W0($)){i0.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let W=Q.latest;K$($,{config:{summary:{content:W}}}).then((H)=>{let X=i0.get($);if(H&&X===Q)X.lastSent=W})},Rz)}function A$($){let Z=i0.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;i0.delete($)}function g4($,Z){return K$($,Z).then(()=>{})}async function K$($,Z){if(W0($))return!1;let J=P0($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>c8($,"patchSettings",async()=>{if(W0($))return;let W=v4($);await S1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:W}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!W0($)}async function C$($){let Z=m$.get($);if(!Z){A$($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,A$($),await Z.queue,m$.delete($)}var _z="https://open.feishu.cn/open-apis/cardkit/v1",Bz=15000,qz,m$,i0,Rz=1500;var d0=S(()=>{o();g();S$();qz=[0,250,750,1500];m$=new Map,i0=new Map});function I4($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function c4($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function Fz($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),W=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,W/Y*100)))}function p3($,Z,J){let Y=Fz($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function u3($){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 m4($,Z){let J=u3($);return Z!=null&&Z>0?`${J}/${u3(Z)}`:`${J}/--`}function l3($,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 p4($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function Uz($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function Oz($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function u4($){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 i3($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function n3($){let Z=$.filter((W)=>W.status==="completed").length,J=$.filter((W)=>W.status==="inProgress").length,Y=$.filter((W)=>W.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function Ez($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${n3($)}`}function a3($){if(!Number.isFinite($)||$<0)return"MISS";if($<60)return`${Math.round($)}s`;let Z=Math.floor($/60),J=Math.round($%60);if(Z<60)return J?`${Z}m ${J}s`:`${Z}m`;let Y=Math.floor(Z/60),Q=Z%60;return Q?`${Y}h ${Q}m`:`${Y}h`}function m8($){return typeof $==="number"&&Number.isFinite($)?$:null}function Tz($){let Z=m8($.startedAtMs),J=m8($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${a3((J-Z)/1000)}`}function Nz($){let Z=m8($);return Z==null?null:u4(Z)}function kz($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=Nz($.preTokens),W=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(W)J.push(`**来源**: ${W}`);return J.length>0?J:["压缩完成,无摘要内容"]}function u8($,Z,J){if($==null||!Number.isFinite($))return null;let Y=p3($,Z,J);return Y?`${Y.used}% · ${m4($,Z)}`:"--"}function p8($){let Z=u4($?.input_tokens??Number.NaN),J=u4($?.cache_read_input_tokens??Number.NaN),Y=u4($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function F2($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",W=Q?"✅":"⏳",H=Q?Tz(Y):"",X=`${W} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,V=kz(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:V.join(`
59
- `)}]}}function o3($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let W of $)Y.push(`- ${Uz(W.status)} ${W.step}`)}else{let W=J.trim();if(Y.push(""),W)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(W);else Y.push("--")}return Y.join(`
60
- `)}function l8($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:Ez($,J)}},expanded:!1,elements:[{tag:"markdown",content:o3($,Z,J)}]}}function U2($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${n3($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:o3($,Z)}]}}function i8($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${i3($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${a3($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${i3($.status)}: ${Oz($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
61
- `)}]}}function l4($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Y=$.userInputs??[],Q=`\uD83D\uDCE5 收到 (${Y.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,W=Y.length>0?[{tag:"collapsible_panel",element_id:M.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((H)=>({tag:"markdown",content:s(H)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...W,{tag:"markdown",element_id:M.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function r3($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function Sz($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function yz($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let W=$.options[Q],H=W.description?` · ${s(W.description)}`:"";Y.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Q}}],elements:[{tag:"markdown",content:`**${s(W.label)}**${H}`}]})}return Y}function d3($,Z,J,Y){if($.length===0)return null;let Q=$.length,W=[];for(let H=0;H<$.length;H++){let X=$[H];if(!X)continue;let V=r3(X,H,Q),z=Y.get(H);if(z){let A=Sz(X,z),K=[`**✅ ${V}**`,`**回答**:${A}`];W.push({tag:"markdown",content:K.join(`
62
- `)});continue}if(H===J){if(W.push({tag:"markdown",content:`**\uD83E\uDD14 ${V}**`}),X.options.length>0)W.push(...yz(X,Z,H));W.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}W.push({tag:"markdown",content:`**⏳ ${V}**`})}return W}function O2($,Z,J,Y="\uD83E\uDD14",Q){let W=J.length,H=Q?.answered??new Map,X=Q?.currentIdx,V=X===void 0&&H.size>0,z=[],A;if(V){A=`${Y} 已回答 · ${W}/${W}`,z.push(...d3(J,Z,X,H)??[]);let K=[...H.values()].reverse().find((B)=>B.user)?.user;if(K)z.push({tag:"markdown",content:`
63
- *— 由 ${K} 回答*`})}else if(X!==void 0&&J[X])A=`${Y} 等你确认 · ${X+1}/${W}`,z.push(...d3(J,Z,X,H)??[]);else if(A=`${Y} 等你确认`,J[0])z.push({tag:"markdown",content:`**${r3(J[0],0,W||1)}**`});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:A}},expanded:!V,elements:z}}var t3=S(()=>{S$()});import{isAbsolute as d8,relative as xz}from"node:path";function d4($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function n4($){return $==="write_stdin"||$.endsWith(".write_stdin")}function bz($){return d4($)||n4($)}function a4($){return $==="FileChange"||$==="fileChange"}function T2($){return $==="WebSearch"||$==="webSearch"}function o4($){return $==="WebFetch"||$==="webFetch"}function s8($){return $==="MCP"}function r4($){return $==="ImageGeneration"||$==="imageGeneration"}function e8($){return $==="Agent"||$==="Task"}function t4($){return $==="Read"}function s4($){return $==="Write"}function e4($){return $==="Edit"||$==="NotebookEdit"}function $6($){return $==="MultiEdit"}function $7($){return $==="Glob"||$==="Grep"||$==="LS"}function Z6($){return $==="TodoWrite"}function J6($){return $==="ExitPlanMode"}function Y6($){return $.startsWith(e3)}function $J($){return Y6($)?$.slice(e3.length):$}function n0($){if(Y6($))return"服务端工具";if(a4($))return"文件变更";if(T2($))return"网页搜索";if(o4($))return"网页读取";if(r4($))return"图片生成";if(t4($))return"读取文件";if(s4($))return"写入文件";if(e4($)||$6($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(Z6($))return"更新待办";if(J6($))return"确认计划";if($==="Task")return"子任务";return bz($)?"Bash":$}function j0($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(Y6($))return J(fz($,Z),80);if(!Z||typeof Z!=="object")return"";if(d4($))return wz(Z);if(n4($))return vz(Z);if(a4($))return J(Iz(Z),80);if(T2($))return J(LJ(Z),80);if(o4($))return J(dz(Z),80);if(s8($))return J(az(Z),80);if(r4($))return J(rz(Z),80);if(e8($))return J(tz(Z),80);if(t4($))return J(cz(Z),80);if(s4($))return J(mz(Z),80);if(e4($))return J(uz(Z),80);if($6($))return J(pz(Z),80);if($7($))return J(lz($,Z),80);if(Z6($))return J(iz(Z),80);if(J6($))return J(N2(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Y of Object.values(Z))if(typeof Y==="string"&&Y)return J(Y,80);return""}function fz($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:$J($),Y=N2(Z?.input);return Y?`${J}: ${Y}`:J}function wz($){let Z=(W,H)=>W.length>H?W.slice(0,H)+"…":W,J=JJ($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Y=J.command;if(!Y)return"";let Q=Y.split(/\r?\n/).map((W)=>W.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(q1(Y),46)}`}function ZJ($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function vz($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${ZJ($)}${J}`}function JJ($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=E9(Z);return{description:Y.description||J,command:Y.command}}function p$($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
57
+ `,f3(Z,J)}}catch(J){A(`feishu: codex trust write failed for ${$}: ${J}`)}try{C3("git init -q",{cwd:$,stdio:"ignore"})}catch{}}function k2(){try{let $=C3(`"${z2()}" login status 2>&1`,{timeout:1e4}).toString();return/Logged in using ChatGPT/i.test($)}catch{return!1}}function t7($){return $.replace(/[^\w一-鿿\-\[\]\*]/g,"_").slice(0,64)}var g3,I3,c3,E0,t,jz=15000,h4="",N3=0,O7=null,Q0,Y0,J0,l,y3=200,x3,P0,j2,a3=31457280,Ez;var s=N(()=>{U0();F1();I$();L0();I();I0();y0();D1();E3();g3=v.feishu.app_id,I3=v.feishu.app_secret,c3=v.runtime.projects_root,E0=new Map;t=new b3.Client({appId:g3,appSecret:I3,disableTokenCache:!1});Q0=new Map,Y0=new Map;J0=new Map;l=new Map;x3=/\*[0-9]{4}-[0-9]{4}(-[0-9]+)?$/;P0=new Map;j2=[0,1000,4000];Ez=new Set([".png",".jpg",".jpeg",".gif",".bmp",".webp"])});import{createHash as s3}from"node:crypto";function s7($,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 e3($,Z){if($!==300315)return!1;return/(?:duplicate\s+(?:element\s*)?id|code\s*1001\s*:\s*duplicate id)/i.test(Z?.message??"")}function D$($){let Z=u0.get($);if(!Z)throw Error(`cardkit card is not registered: ${$}`);return Z}function W$($){return!u0.has($)}function p0($,Z,J){u0.set($,{sequence:0,queue:Promise.resolve(),elementCount:Z,contentFingerprints:new Map,deadElements:new Set,failedAdds:new Map,failedReplacements:new Set,onFailure:J,closing:!1})}function e7($){return u0.get($)?.elementCount??0}function $J($){let Z=u0.get($);return Z?[...Z.contentFingerprints.keys()].filter((J)=>!Z.deadElements.has(J)):[]}function C1($,Z){return u0.get($)?.deadElements.has(Z)??!1}function ZJ($,Z){let J=u0.get($);J?.deadElements.delete(Z),J?.failedAdds.delete(Z),J?.failedReplacements.delete(Z)}function d4($){let Z=D$($);return Z.sequence+=1,Z.sequence}function JJ($,Z){$.deadElements.add(Z)}function YJ($){return s3("sha256").update(JSON.stringify($,(Z,J)=>Z==="element_id"?void 0:J)).digest("hex")}function Cz($,Z,J){let Y=[...$.contentFingerprints].filter(([Q])=>Q!==Z).map(([,Q])=>Q);if(J&&Z!==M.footer)Y.push(J);return s3("sha256").update(Y.sort().join(`
58
+ `)).digest("hex")}async function b1($,Z,J){let Y=await Q$(),Q=await fetch(`${Sz}${Z}`,{method:$,headers:{Authorization:`Bearer ${Y}`,"Content-Type":"application/json"},...J?{body:JSON.stringify(J)}:{},signal:AbortSignal.timeout(yz)}),W=await Q.json();if(!Q.ok||W?.code!==0){let H=typeof W?.code==="number"?W.code:Q.status,X=Q.headers.get("x-tt-logid")??Q.headers.get("x-request-id")??Q.headers.get("request-id")??void 0,V=Error(`cardkit ${$} ${Z}: HTTP ${Q.status} code=${String(W?.code??"MISS")} msg=${W?.msg??"MISS"}${X?` log_id=${X}`:""}`);throw V.code=H,V.httpStatus=Q.status,V.logId=X,V}return W?.data}function wz($){return new Promise((Z)=>setTimeout(Z,$))}function fz($){if(typeof $!=="object"||$===null)return!1;let Z=$.code;return Z===300309||Z===200850}async function vz($){let Z=d4($);await b1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify({config:{streaming_mode:!0}}),sequence:Z})}async function $8($,Z,J,Y,Q=!1,W={}){let H=(X)=>{let V=typeof X==="object"&&X!==null?X:null,z={cardId:$,operation:Z,elementId:W.elementId,targetElementId:W.targetElementId,code:V?.code,httpStatus:V?.httpStatus,logId:V?.logId,message:X instanceof Error?X.message:String(X)};if(s7(z.code,z))z.capacityFingerprint=Cz(D$($),W.elementId,W.contentFingerprint);try{if(!Q)D$($).onFailure?.(z.code,z)}catch(G){A(`cardkit failure callback ${$}: ${G}`)}try{Y?.(z)}catch(G){A(`cardkit per-call failure callback ${$}: ${G}`)}};try{await J();return}catch(X){if(!fz(X)){A(`cardkit ${Z} ${$}: ${X}`),H(X);return}A(`cardkit ${Z} ${$}: streaming closed (code=${X.code}) — reopening`)}try{await vz($)}catch(X){A(`cardkit STREAMING_REOPEN_FAILED ${$}: ${X}`),H(X);return}try{await J()}catch(X){A(`cardkit ${Z} ${$} retry-after-reopen: ${X}`),H(X)}}function hz($){return typeof $==="object"&&$!==null&&$.code===200740}async function t0($,Z={}){let J=Z.retryDelaysMs?.length?Z.retryDelaysMs:xz,Y=null;for(let Q=0;Q<J.length;Q++){let W=J[Q]??0;if(W>0)await wz(W);try{let H=await b1("POST","/cards/id_convert",{message_id:$});if(typeof H?.card_id!=="string"||!H.card_id)throw Error("cardkit POST /cards/id_convert: missing card_id");return H.card_id}catch(H){if(Y=H,!hz(H)||Q===J.length-1)throw H;let X=J[Q+1]??0;A(`cardkit id_convert ${$}: empty result, retry ${Q+2}/${J.length} in ${X}ms`)}}throw Y}async function b0($){let Z=u0.get($);if(!Z)return;await Z.queue}function X0($,Z,J={},Y){if(W$($))return Promise.resolve();let Q=D$($);if(Q.closing)return Promise.resolve();let W=q$(Z),H=W.element_id,X=YJ(W),V=()=>{if(!H)return;JJ(Q,H),Q.failedAdds.set(H,J)};return Q.queue=Q.queue.then(()=>$8($,"addElement",async()=>{let z=d4($);if(await b1("POST",`/cards/${$}/elements`,{type:J.type??"append",...J.targetElementId?{target_element_id:J.targetElementId}:{},elements:JSON.stringify([W]),sequence:z}),Q.elementCount+=1,H!==M.footer)Q.contentFingerprints.set(H??`#${z}`,X);if(H)Q.deadElements.delete(H),Q.failedAdds.delete(H),Q.failedReplacements.delete(H)},(z)=>{V(),Y?.(z.code,z)},!1,{elementId:H,targetElementId:J.targetElementId,contentFingerprint:X})),Q.queue}function n($,Z,J,Y,Q=!0){if(W$($))return Promise.resolve();let W=D$($);if(W.closing)return Promise.resolve();let H=q$(J),X=YJ(H),V=()=>{JJ(W,Z),W.failedReplacements.add(Z)};return W.queue=W.queue.then(()=>$8($,`replaceElement ${Z}`,async()=>{let z=W.failedAdds.get(Z);if(W.deadElements.has(Z)&&!z&&!W.failedReplacements.has(Z))return;let G=d4($);if(z)await b1("POST",`/cards/${$}/elements`,{type:z.type??"append",...z.targetElementId?{target_element_id:z.targetElementId}:{},elements:JSON.stringify([H]),sequence:G}),W.elementCount++;else await b1("PUT",`/cards/${$}/elements/${Z}`,{element:JSON.stringify(H),sequence:G});if(W.deadElements.delete(Z),W.failedAdds.delete(Z),W.failedReplacements.delete(Z),Z!==M.footer)W.contentFingerprints.set(Z,X)},(z)=>{if(Q)V();Y?.(z.code,z)},!Q,{elementId:Z,contentFingerprint:X})),W.queue}async function R0($,Z,J,Y={}){if(W$($))return!1;let Q=D$($);if(Q.closing)return!1;let W=!1;return await n($,Z,J,()=>{W=!0},Y.notifyCardFailure!==!1),!W&&!Q.deadElements.has(Z)}async function M$($,Z,J={}){return(await n4($,Z,J)).landed}async function n4($,Z,J={}){if(W$($))return{landed:!1};let Y=D$($);if(Y.closing)return{landed:!1};let Q=Z.element_id,W;return await X0($,Z,J,(H,X)=>{W=X}),{landed:!W&&!(Q&&Y.deadElements.has(Q)),...W?{failure:W}:{}}}function H$($,Z){if(W$($)||u0.get($)?.closing)return;let J=(Z??"").replace(/\s+/g," ").trim();if(!J)return;let Y=a$.get($);if(!Y)Y={latest:J,lastSent:"",timer:null},a$.set($,Y);else Y.latest=J;if(Y.timer)return;Y.timer=setTimeout(()=>{let Q=a$.get($);if(!Q)return;if(W$($)){a$.delete($);return}if(Q.timer=null,Q.latest===Q.lastSent)return;let W=Q.latest;_0($,{config:{summary:{content:W}}}).then((H)=>{let X=a$.get($);if(H&&X===Q)X.lastSent=W})},bz)}function A0($){let Z=a$.get($);if(!Z)return;if(Z.timer)clearTimeout(Z.timer),Z.timer=null;a$.delete($)}function a4($,Z){return _0($,Z).then(()=>{})}async function _0($,Z){if(W$($))return!1;let J=D$($);if(J.closing)return!1;let Y=!1,Q=!1;return J.queue=J.queue.then(()=>$8($,"patchSettings",async()=>{if(W$($))return;let W=d4($);await b1("PATCH",`/cards/${$}/settings`,{settings:JSON.stringify(Z),sequence:W}),Y=!0},()=>{Q=!0},!0)),await J.queue,Y&&!Q&&!W$($)}async function C0($){let Z=u0.get($);if(!Z){A0($);return}if(Z.closing){await Z.queue;return}Z.closing=!0,A0($),await Z.queue,u0.delete($)}var Sz="https://open.feishu.cn/open-apis/cardkit/v1",yz=15000,xz,u0,a$,bz=1500;var o$=N(()=>{s();I();y0();xz=[0,250,750,1500];u0=new Map,a$=new Map});function o4($){if(!$)return null;return typeof $.total_tokens==="number"&&Number.isFinite($.total_tokens)?$.total_tokens:null}function r4($){return typeof $==="number"&&Number.isFinite($)&&$>0?$:null}function gz($,Z,J=12000){if(Z==null||Z<=0)return null;if(Z<=J)return 0;let Y=Z-J,Q=Math.max(0,$-J),W=Math.max(0,Y-Q);return Math.round(Math.min(100,Math.max(0,W/Y*100)))}function WJ($,Z,J){let Y=gz($,Z,J??12000);if(Y==null)return null;return{used:Math.min(100,Math.max(0,100-Y)),remaining:Y}}function QJ($){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 t4($,Z){let J=QJ($);return Z!=null&&Z>0?`${J}/${QJ(Z)}`:`${J}/--`}function HJ($,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 e4($){return JSON.stringify({objective:$.objective,status:$.status,tokenBudget:$.tokenBudget})}function Iz($){switch($){case"pending":return"☐";case"inProgress":return"\uD83D\uDD04";case"completed":return"✅";default:return"·"}}function cz($,Z){return $.length>Z?$.slice(0,Z)+"…":$}function s4($){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 XJ($){switch($){case"active":return"进行中";case"paused":return"已暂停";case"blocked":return"受阻";case"usageLimited":return"额度受限";case"budgetLimited":return"预算受限";case"complete":return"已完成";default:return $}}function zJ($){let Z=$.filter((W)=>W.status==="completed").length,J=$.filter((W)=>W.status==="inProgress").length,Y=$.filter((W)=>W.status==="pending").length,Q=[`${$.length} 项`];if(J)Q.push(`${J} 进行中`);if(Z)Q.push(`${Z} 完成`);if(Y)Q.push(`${Y} 待办`);return Q.join(" · ")}function mz($,Z=""){let J=Z.trim();if($.length===0)return J?"\uD83D\uDCCB 计划草稿":"\uD83D\uDCCB 计划更新";return`\uD83D\uDCCB 计划更新 · ${zJ($)}`}function GJ($){if(!Number.isFinite($)||$<0)return"MISS";if($<60)return`${Math.round($)}s`;let Z=Math.floor($/60),J=Math.round($%60);if(Z<60)return J?`${Z}m ${J}s`:`${Z}m`;let Y=Math.floor(Z/60),Q=Z%60;return Q?`${Y}h ${Q}m`:`${Y}h`}function Z8($){return typeof $==="number"&&Number.isFinite($)?$:null}function uz($){let Z=Z8($.startedAtMs),J=Z8($.completedAtMs);if(Z==null||J==null||J<Z)return"";return` · 耗时 ${GJ((J-Z)/1000)}`}function pz($){let Z=Z8($);return Z==null?null:s4(Z)}function lz($,Z){if(!Z)return["压缩中..."];let J=[],Y=typeof $.trigger==="string"&&$.trigger.trim()?$.trigger.trim():"",Q=pz($.preTokens),W=typeof $.sourceType==="string"&&$.sourceType.trim()?$.sourceType.trim():"";if(Y)J.push(`**触发**: ${Y}`);if(Q)J.push(`**压缩前**: ${Q} tokens`);if(W)J.push(`**来源**: ${W}`);return J.length>0?J:["压缩完成,无摘要内容"]}function J8($,Z,J){if($==null||!Number.isFinite($))return null;let Y=WJ($,Z,J);return Y?`${Y.used}% · ${t4($,Z)}`:"--"}function Y8($){let Z=s4($?.input_tokens??Number.NaN),J=s4($?.cache_read_input_tokens??Number.NaN),Y=s4($?.output_tokens??Number.NaN);return`└ 入 ${Z} | 缓 ${J} | 出 ${Y}`}function S2($,Z,J){let Y=Z&&typeof Z==="object"?Z:{},Q=Y.phase==="end"||Y.phase==="event",W=Q?"✅":"⏳",H=Q?uz(Y):"",X=`${W} \uD83D\uDEA8 上下文压缩 #${$+1}${H}`,V=lz(Y,Q);return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:X}},expanded:!1,elements:[{tag:"markdown",content:V.join(`
59
+ `)}]}}function AJ($,Z,J=""){let Y=["**\uD83D\uDCCB 当前计划**"],Q=Z?.trim();if(Q)Y.push(""),Y.push(Q);if($.length>0){Y.push("");for(let W of $)Y.push(`- ${Iz(W.status)} ${W.step}`)}else{let W=J.trim();if(Y.push(""),W)Y.push("正在生成计划草稿..."),Y.push(""),Y.push(W);else Y.push("--")}return Y.join(`
60
+ `)}function Q8($,Z,J="",Y){return{tag:"collapsible_panel",element_id:Y,header:{title:{tag:"plain_text",content:mz($,J)}},expanded:!1,elements:[{tag:"markdown",content:AJ($,Z,J)}]}}function y2($,Z,J){let Y=$.length>0?`\uD83D\uDCCB 当前计划 · ${zJ($)}`:"\uD83D\uDCCB 当前计划";return{tag:"collapsible_panel",element_id:J,header:{title:{tag:"plain_text",content:Y}},expanded:!0,elements:[{tag:"markdown",content:AJ($,Z)}]}}function W8($,Z){let J=Number.isFinite($.tokensUsed)?String($.tokensUsed):"MISS",Y=$.tokenBudget==null?"":Number.isFinite($.tokenBudget)?` / ${$.tokenBudget}`:" / MISS",Q=[`**\uD83C\uDFAF 当前目标** · ${XJ($.status)}`,"",$.objective,"",`- 用量: ${J}${Y} tokens`,`- 用时: ${GJ($.timeUsedSeconds)}`];return{tag:"collapsible_panel",element_id:Z,header:{title:{tag:"plain_text",content:`\uD83C\uDFAF 目标更新 · ${XJ($.status)}: ${cz($.objective,48)}`}},expanded:!1,elements:[{tag:"markdown",content:Q.join(`
61
+ `)}]}}function $9($){let Z=$.provider==="claude"?"Claude":"Codex",J=$.kind==="card_full"?[{tag:"markdown",content:`\uD83D\uDCE8 接续上一张(同一轮 ${Z},前卡写满或写入受限)`}]:$.kind==="bg_task_resume"?[{tag:"markdown",content:`\uD83D\uDD01 后台任务完成,${Z} 继续处理结果 #${$.turn}`}]:$.kind==="scheduled_wakeup"?[{tag:"markdown",content:`⏰ 定时任务触发,${Z} 正在执行巡检 #${$.turn}`}]:[],Y=$.userInputs??[],Q=`\uD83D\uDCE5 收到 (${Y.length}) ${$.directStart?"\uD83D\uDE80":`#${$.turn}`}`,W=Y.length>0?[{tag:"collapsible_panel",element_id:M.userInput,header:{title:{tag:"plain_text",content:Q}},expanded:!1,elements:Y.map((H)=>({tag:"markdown",content:d(H)}))}]:[];return{schema:"2.0",config:{streaming_mode:!0,summary:{content:"[Lodestar 正在生成…]"},streaming_config:{print_frequency_ms:{default:60,android:60,ios:60,pc:30},print_step:{default:2,android:2,ios:2,pc:4},print_strategy:"fast"}},body:{elements:[...J,...W,{tag:"markdown",element_id:M.footer,content:$.initialFooter??"Waiting...(0s)"}]}}}function _J($,Z,J){let Y=$.question.trim()||`问题 ${Z+1}`;return`${Z+1}/${J} · ${Y}`}function iz($,Z){if(!Z)return"?";return Z.customText??(Z.optionIdx!==void 0?$.options[Z.optionIdx]?.label:void 0)??"?"}function dz($,Z,J){let Y=[];for(let Q=0;Q<$.options.length;Q++){let W=$.options[Q],H=W.description?` · ${d(W.description)}`:"";Y.push({tag:"interactive_container",background_style:"default",has_border:!0,corner_radius:"6px",padding:"8px 12px",margin:"4px 0px 4px 0px",behaviors:[{type:"callback",value:{kind:"ask",tool_use_id:Z,question_idx:J,option_idx:Q}}],elements:[{tag:"markdown",content:`**${d(W.label)}**${H}`}]})}return Y}function VJ($,Z,J,Y){if($.length===0)return null;let Q=$.length,W=[];for(let H=0;H<$.length;H++){let X=$[H];if(!X)continue;let V=_J(X,H,Q),z=Y.get(H);if(z){let G=iz(X,z),_=[`**✅ ${V}**`,`**回答**:${G}`];W.push({tag:"markdown",content:_.join(`
62
+ `)});continue}if(H===J){if(W.push({tag:"markdown",content:`**\uD83E\uDD14 ${V}**`}),X.options.length>0)W.push(...dz(X,Z,H));W.push({tag:"markdown",content:"_\uD83D\uDCAC 也可以直接在群里回复你的答案(裸词命令 `hi`/`stop`/`kill`/`restart`/`clear`/`model` 仍然优先)_"});continue}W.push({tag:"markdown",content:`**⏳ ${V}**`})}return W}function f1($,Z,J,Y="\uD83E\uDD14",Q){let W=J.length,H=Q?.answered??new Map,X=Q?.currentIdx,V=X===void 0&&H.size>0,z=[],G;if(Q?.waitingFor)G=Q.waitingFor==="notification"?"⏳ 等待通知回复完成":"⏳ 提问排队中",z.push({tag:"markdown",content:Q.waitingFor==="notification"?"请先完成或取消通知回复,再回答这个问题。":"先回答当前问题,再显示这个提问。"});else if(V){G=`${Y} 已回答 · ${W}/${W}`,z.push(...VJ(J,Z,X,H)??[]);let _=[...H.values()].reverse().find((B)=>B.user)?.user;if(_)z.push({tag:"markdown",content:`
63
+ *— 由 ${_} 回答*`})}else if(X!==void 0&&J[X])G=`${Y} 等你确认 · ${X+1}/${W}`,z.push(...VJ(J,Z,X,H)??[]);else if(G=`${Y} 等你确认`,J[0])z.push({tag:"markdown",content:`**${_J(J[0],0,W||1)}**`});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:G}},expanded:!V&&!Q?.waitingFor,elements:z}}var KJ=N(()=>{y0()});import{isAbsolute as H8,relative as nz}from"node:path";function J9($){return $==="Bash"||$==="exec_command"||$.endsWith(".exec_command")}function Y9($){return $==="write_stdin"||$.endsWith(".write_stdin")}function oz($){return J9($)||Y9($)}function Q9($){return $==="FileChange"||$==="fileChange"}function b2($){return $==="WebSearch"||$==="webSearch"}function W9($){return $==="WebFetch"||$==="webFetch"}function _8($){return $==="MCP"}function H9($){return $==="ImageGeneration"||$==="imageGeneration"}function K8($){return $==="Agent"||$==="Task"}function X9($){return $==="Read"}function V9($){return $==="Write"}function z9($){return $==="Edit"||$==="NotebookEdit"}function G9($){return $==="MultiEdit"}function B8($){return $==="Glob"||$==="Grep"||$==="LS"}function A9($){return $==="TodoWrite"}function _9($){return $==="ExitPlanMode"}function K9($){return $.startsWith(qJ)}function LJ($){return K9($)?$.slice(qJ.length):$}function r$($){if(K9($))return"服务端工具";if(Q9($))return"文件变更";if(b2($))return"网页搜索";if(W9($))return"网页读取";if(H9($))return"图片生成";if(X9($))return"读取文件";if(V9($))return"写入文件";if(z9($)||G9($))return"编辑文件";if($==="Glob")return"匹配文件";if($==="Grep")return"搜索文件";if($==="LS")return"列目录";if(A9($))return"更新待办";if(_9($))return"确认计划";if($==="Task")return"子任务";return oz($)?"Bash":$}function F$($,Z){let J=(Y,Q)=>Y.length>Q?Y.slice(0,Q)+"…":Y;if(K9($))return J(rz($,Z),80);if(!Z||typeof Z!=="object")return"";if(J9($))return tz(Z);if(Y9($))return sz(Z);if(Q9($))return J(ZG(Z),80);if(b2($))return J(CJ(Z),80);if(W9($))return J(VG(Z),80);if(_8($))return J(GG(Z),80);if(H9($))return J(_G(Z),80);if(K8($))return J(KG(Z),80);if(X9($))return J(JG(Z),80);if(V9($))return J(YG(Z),80);if(z9($))return J(QG(Z),80);if(G9($))return J(WG(Z),80);if(B8($))return J(HG($,Z),80);if(A9($))return J(XG(Z),80);if(_9($))return J(C2(Z)||"提交计划",80);switch($){case"Skill":return J(String(Z.skill??""),80)}for(let Y of Object.values(Z))if(typeof Y==="string"&&Y)return J(Y,80);return""}function rz($,Z){let J=typeof Z?.tool==="string"&&Z.tool?Z.tool:LJ($),Y=C2(Z?.input);return Y?`${J}: ${Y}`:J}function tz($){let Z=(W,H)=>W.length>H?W.slice(0,H)+"…":W,J=jJ($);if(J.description)return Z(J.description.replace(/\s+/g," "),80);let Y=J.command;if(!Y)return"";let Q=Y.split(/\r?\n/).map((W)=>W.trim()).filter(Boolean);if(Q.length<=1)return Z(Y.replace(/\s+/g," "),80);return`Shell 脚本 · ${Q.length} 行 · ${Z(R1(Y),46)}`}function PJ($){let Z=typeof $?.chars==="string"?$.chars:"";if(Z==="")return"读取会话输出";if(Z==="\x03")return"中断会话";return"发送输入"}function sz($){let Z=$?.session_id??$?.sessionId,J=Z===void 0?"":` ${Z}`;return`${PJ($)}${J}`}function jJ($){let Z=String($?.command??$?.cmd??$?.script??""),J=String($?.description??$?.reason??"").trim(),Y=I6(Z);return{description:Y.description||J,command:Y.command}}function l0($,Z=""){let J="```";while($.includes(J))J+="`";return`${J}${Z}
64
64
  ${$}
65
- ${J}`}function X0($,Z=Cz,J=""){if($.length<=Z)return p$($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,p$(`${Y}
65
+ ${J}`}function X$($,Z=az,J=""){if($.length<=Z)return l0($,J);let Y=$.slice(0,Z).trimEnd();return[`_已截断: 仅显示前 ${Z} / ${$.length} 字符。_`,l0(`${Y}
66
66
  ... output 已截断 ...`,J)].join(`
67
- `)}function w($){return"`"+String($??"").replace(/`/g,"'")+"`"}function b$($,Z=3000){return p$(JSON.stringify($??null,null,2).slice(0,Z),"json")}function N2($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Y=Z[J];if(typeof Y==="string"&&Y.length>0)return Y}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function YJ($,Z,J){let Y=JJ($),Q=Y.command,W=Y.description,H=[];if(W)H.push(`**目的**: ${W}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${w(X)}`);if($?.source)H.push(`**source**: ${w($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(p$(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(X0(Z));return H.join(`
68
- `)}function QJ($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${ZJ($)}`),Q!==void 0)Y.push(`**session**: ${w(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let W=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(p$(W))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(X0(Z));return Y.join(`
69
- `)}function WJ($){return Array.isArray($?.changes)?$.changes:[]}function HJ($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function E2($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&d8(J)&&d8(Z)){let Y=xz(Z,J);if(Y&&!Y.startsWith("..")&&!d8(Y))return Y}return J}function hz($){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 XJ($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function a8($){let Z=hz($);if(XJ($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function o8($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function r8($){let Z=0,J=0;for(let Y of $.split(/\r?\n/)){if(Y.startsWith("+++")||Y.startsWith("---"))continue;if(Y.startsWith("+"))Z++;if(Y.startsWith("-"))J++}return{added:Z,removed:J}}function VJ($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function t8($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function gz($){return $.length>1800?$.slice(0,1800)+`
70
- ... diff 已截断 ...`:$}function Iz($){let Z=WJ($),J=HJ($);if(Z.length===0){let V=typeof $?.reason==="string"?$.reason.trim():"",z=$?.grantRoot?E2($.grantRoot):"";if(V&&z)return`${V} · ${z}`;return V||(z?`申请修改 ${z}`:"")}let Y=Z.map((V)=>r8(o8(V))).reduce(VJ,{added:0,removed:0}),Q=t8(Y),W=[...new Set(Z.map(a8))],H=E2(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${W[0]} ${H}${X}`;return`${Z.length} 个文件 · ${W.join("/")} · ${H} 等${X}`}function zJ($,Z,J){let Y=WJ($),Q=HJ($),W=[];if(Y.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"";if(z)W.push(`**原因**: ${z}`);if($?.grantRoot)W.push(`**范围**: ${w(E2($.grantRoot))}`);if(J)W.push(""),W.push(J);if(Z!=null)W.push(""),W.push("---"),W.push("**output:**"),W.push(p$(Z.slice(0,3000)));return W.length>0?W.join(`
71
- `):p$(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((z)=>r8(o8(z))).reduce(VJ,{added:0,removed:0}),X=t8(H);if(W.push(`**文件**: ${Y.length} 个`),X)W.push(`**行数**: ${X}`);if($?.status)W.push(`**状态**: ${w($.status)}`);let V=Y.slice(0,5);for(let z of V){let A=o8(z),K=t8(r8(A)),B=E2(z?.path,Q),q=K?`**${a8(z)}** ${w(B)} · ${K}`:`**${a8(z)}** ${w(B)}`;W.push(""),W.push(q);let L=XJ(z);if(L)W.push(`来自 ${w(E2(L,Q))}`);W.push(A?p$(gz(A),"diff"):"_无 diff 内容_")}if(Y.length>V.length)W.push(""),W.push(`还有 ${Y.length-V.length} 个文件未展开显示。`);if(J)W.push(""),W.push(J);return W.join(`
72
- `)}function M0($){return String($?.file_path??$?.path??$?.notebook_path??"")}function cz($){let Z=M0($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function mz($){let Z=M0($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function uz($){let Z=M0($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function pz($){let Z=M0($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function lz($,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 GJ($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function iz($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let W=GJ(Q?.status);J.set(W,(J.get(W)??0)+1)}let Y=[...J.entries()].map(([Q,W])=>`${Q} ${W}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function dz($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function C1($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(X0(Z,1200))}function AJ($,Z,J){let Y=[],Q=M0($);if(Q)Y.push(`**路径**: ${w(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${w($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${w($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
73
- `):b$($??{},2000)}function KJ($,Z,J){let Y=[],Q=M0($),W=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${w(Q)}`);if(W){let H=W.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${W.length} 字符`),Y.push(X0(W,1200))}if(J)Y.push(""),Y.push(J);return C1(Y,Z),Y.length>0?Y.join(`
74
- `):b$($??{},2000)}function _J($,Z,J){let Y=[],Q=M0($);if(Q)Y.push(`**路径**: ${w(Q)}`);if($?.cell_id)Y.push(`**cell**: ${w($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${w($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(X0($.old_string,800));let W=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(W)Y.push(""),Y.push("**替换为**"),Y.push(X0(W,800));if(J)Y.push(""),Y.push(J);return C1(Y,Z),Y.length>0?Y.join(`
75
- `):b$($??{},2000)}function BJ($,Z,J){let Y=[],Q=M0($),W=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${w(Q)}`);Y.push(`**编辑**: ${W.length} 处`);for(let[H,X]of W.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${X?.replace_all?" · 全局替换":""}**`),typeof X?.old_string==="string")Y.push("查找:"),Y.push(X0(X.old_string,500));if(typeof X?.new_string==="string")Y.push("替换为:"),Y.push(X0(X.new_string,500))}if(W.length>5)Y.push(""),Y.push(`还有 ${W.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return C1(Y,Z),Y.join(`
76
- `)}function qJ($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${w(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${w(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${w(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${w(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${w(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${w(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${w(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${w(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(w).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return C1(Q,J),Q.join(`
77
- `)}function RJ($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let W of Y.slice(0,12)){let H=GJ(W?.status),X=String(W?.content??W?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${X}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return C1(Q,Z),Q.join(`
78
- `)}function Z7($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function J7($,Z){return Z7(Z)??$?.action??{}}function Y7($,Z){let J=J7($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((W)=>typeof W==="string"&&W.length>0):[],Q=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Y.length>0?Y:Q?[Q]:[]}function Q7($,Z){let J=J7($,Z);return String(J?.url??$?.url??"")}function LJ($){let Z=Y7($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=Q7($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function nz($,Z){let J=Y7($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=Q7($,Z);if(Y)return Y;return LJ($)}function PJ($,Z,J){let Y=J7($,Z),Q=Y7($,Z),W=Q7($,Z),H=[],X=typeof Y?.type==="string"?Y.type:"";if(X==="search"||Q.length>0){if(H.push("**动作**: 搜索"),Q.length>0){H.push(""),H.push("**查询**");for(let V of Q.slice(0,6))H.push(`- ${w(V)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(X==="open_page"){if(H.push("**动作**: 打开页面"),W)H.push(`**URL**: ${w(W)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),W)H.push(`**URL**: ${w(W)}`);if(Y?.pattern)H.push(`**关键词**: ${w(Y.pattern)}`)}else if(H.push(`**动作**: ${X?w(X):"网页搜索"}`),W)H.push(`**URL**: ${w(W)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!W&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(p$(Z.slice(0,3000),"json"));return H.join(`
79
- `)}function DJ($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${w($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return C1(Y,Z),Y.join(`
80
- `)}function az($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=N2($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function jJ($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${w($.server)}`);if($?.tool)Y.push(`**tool**: ${w($.tool)}`);let Q=$?.arguments;if(Q&&typeof Q==="object"&&Object.keys(Q).length>0){if(Y.length>0)Y.push("");Y.push("**arguments**"),Y.push(b$(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let W=Z7(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),W&&Array.isArray(W.content)){let H=W.content.map((X)=>typeof X?.text==="string"?X.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
81
- `).slice(0,3000));if(W.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(b$(W.structuredContent,2000));if(H.length===0&&!W.structuredContent)Y.push(b$(W,3000))}else Y.push(W?b$(W,3000):p$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
82
- `):b$($??{},2000)}function oz($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${w(typeof Z?.tool==="string"&&Z.tool?Z.tool:$J($))}`],W=Z?.input;if(W&&typeof W==="object")if(Q.push(""),Q.push("**input**"),Object.keys(W).length>0)Q.push(b$(W,2000));else Q.push("_provider 未提供结构化 input_");else if(W!=null&&W!=="")Q.push(`**input**: ${w(W)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(X0(J,3000));return Q.join(`
83
- `)}function rz($){let Z=typeof $?.revisedPrompt==="string"?$.revisedPrompt:"",J=typeof $?.status==="string"?$.status:"";return Z||J}function MJ($,Z,J){let Y=[];if($?.status)Y.push(`**状态**: ${w($.status)}`);if($?.revisedPrompt){if(Y.length>0)Y.push("");Y.push("**提示词**"),Y.push(String($.revisedPrompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null&&Z.trim())Y.push(""),Y.push("---"),Y.push("**输出**"),Y.push(w(Z.trim()));return Y.length>0?Y.join(`
84
- `):b$($??{},2000)}function tz($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",W=Y||Q||J;return Z&&W?`${Z}: ${W}`:W||Z}function i4($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${w($.tool)}`);if($?.model)Y.push(`**model**: ${w($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${w($.subagent_type)}`);if($?.prompt){if(Y.length>0)Y.push("");Y.push("**prompt**"),Y.push(String($.prompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){Y.push(""),Y.push("---"),Y.push("**状态**");let Q=Z7(Z);Y.push(Q?b$(Q,3000):p$(Z.slice(0,3000)))}return Y.length>0?Y.join(`
85
- `):b$($??{},2000)}function F0($,Z,J,Y,Q="⏳",W){let H=T2(Z)&&Y!=null?nz(J,Y):j0(Z,J),X=H.length>80?H.slice(0,80)+"…":H,V=n0(Z),z=X?`${Q} \uD83D\uDD27 ${V}: ${X}`:`${Q} \uD83D\uDD27 ${V}`,A=W?`
86
-
87
- ${W}`:"",K=d4(Z)?YJ(J,Y,W):n4(Z)?QJ(J,Y,W):Y6(Z)?oz(Z,J,Y,W):a4(Z)?zJ(J,Y,W):T2(Z)?PJ(J,Y,W):o4(Z)?DJ(J,Y,W):s8(Z)?jJ(J,Y,W):r4(Z)?MJ(J,Y,W):t4(Z)?AJ(J,Y,W):s4(Z)?KJ(J,Y,W):e4(Z)?_J(J,Y,W):$6(Z)?BJ(J,Y,W):$7(Z)?qJ(Z,J,Y,W):Z6(Z)?RJ(J,Y,W):J6(Z)?i4({prompt:N2(J)||"提交计划"},Y,W):e8(Z)?i4(J,Y,W):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+A+(Y!=null?`
67
+ `)}function f($){return"`"+String($??"").replace(/`/g,"'")+"`"}function w0($,Z=3000){return l0(JSON.stringify($??null,null,2).slice(0,Z),"json")}function C2($){if(!$||typeof $!=="object")return"";let Z=$;for(let J of["query","prompt","path","file_path","url","name","id"]){let Y=Z[J];if(typeof Y==="string"&&Y.length>0)return Y}for(let J of Object.values(Z))if(typeof J==="string"&&J.length>0)return J;return""}function RJ($,Z,J){let Y=jJ($),Q=Y.command,W=Y.description,H=[];if(W)H.push(`**目的**: ${W}`);let X=$?.cwd??$?.workdir;if(X)H.push(`**cwd**: ${f(X)}`);if($?.source)H.push(`**source**: ${f($.source)}`);if(H.length>0)H.push("");if(H.push("**命令**"),H.push(l0(Q||"(空命令)","bash")),J)H.push(""),H.push(J);if(Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(X$(Z));return H.join(`
68
+ `)}function DJ($,Z,J){let Y=[],Q=$?.session_id??$?.sessionId;if(Y.push(`**操作**: ${PJ($)}`),Q!==void 0)Y.push(`**session**: ${f(Q)}`);if(typeof $?.chars==="string"&&$.chars.length>0){let W=$.chars==="\x03"?"^C":$.chars;Y.push(""),Y.push("**输入**"),Y.push(l0(W))}if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("---"),Y.push("**output:**"),Y.push(X$(Z));return Y.join(`
69
+ `)}function MJ($){return Array.isArray($?.changes)?$.changes:[]}function FJ($){let Z=$?.cwd??$?.grantRoot;return typeof Z==="string"&&Z.length>0?Z:void 0}function x2($,Z){let J=String($??"");if(!J)return"(无 path)";if(Z&&H8(J)&&H8(Z)){let Y=nz(Z,J);if(Y&&!Y.startsWith("..")&&!H8(Y))return Y}return J}function ez($){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 UJ($){return $?.kind?.move_path??$?.kind?.movePath??$?.move_path??$?.movePath}function V8($){let Z=ez($);if(UJ($))return Z==="update"?"移动/修改":"移动";switch(Z){case"add":return"新增";case"delete":return"删除";case"update":return"修改";default:return"变更"}}function z8($){let Z=$?.diff??$?.unified_diff;return typeof Z==="string"?Z:""}function G8($){let Z=0,J=0;for(let Y of $.split(/\r?\n/)){if(Y.startsWith("+++")||Y.startsWith("---"))continue;if(Y.startsWith("+"))Z++;if(Y.startsWith("-"))J++}return{added:Z,removed:J}}function OJ($,Z){return{added:$.added+Z.added,removed:$.removed+Z.removed}}function A8($){return $.added>0||$.removed>0?`+${$.added} -${$.removed}`:""}function $G($){return $.length>1800?$.slice(0,1800)+`
70
+ ... diff 已截断 ...`:$}function ZG($){let Z=MJ($),J=FJ($);if(Z.length===0){let V=typeof $?.reason==="string"?$.reason.trim():"",z=$?.grantRoot?x2($.grantRoot):"";if(V&&z)return`${V} · ${z}`;return V||(z?`申请修改 ${z}`:"")}let Y=Z.map((V)=>G8(z8(V))).reduce(OJ,{added:0,removed:0}),Q=A8(Y),W=[...new Set(Z.map(V8))],H=x2(Z[0]?.path,J),X=Q?` · ${Q}`:"";if(Z.length===1)return`${W[0]} ${H}${X}`;return`${Z.length} 个文件 · ${W.join("/")} · ${H} 等${X}`}function EJ($,Z,J){let Y=MJ($),Q=FJ($),W=[];if(Y.length===0){let z=typeof $?.reason==="string"?$.reason.trim():"";if(z)W.push(`**原因**: ${z}`);if($?.grantRoot)W.push(`**范围**: ${f(x2($.grantRoot))}`);if(J)W.push(""),W.push(J);if(Z!=null)W.push(""),W.push("---"),W.push("**output:**"),W.push(l0(Z.slice(0,3000)));return W.length>0?W.join(`
71
+ `):l0(JSON.stringify($??{},null,2).slice(0,2000))}let H=Y.map((z)=>G8(z8(z))).reduce(OJ,{added:0,removed:0}),X=A8(H);if(W.push(`**文件**: ${Y.length} 个`),X)W.push(`**行数**: ${X}`);if($?.status)W.push(`**状态**: ${f($.status)}`);let V=Y.slice(0,5);for(let z of V){let G=z8(z),_=A8(G8(G)),B=x2(z?.path,Q),q=_?`**${V8(z)}** ${f(B)} · ${_}`:`**${V8(z)}** ${f(B)}`;W.push(""),W.push(q);let L=UJ(z);if(L)W.push(`来自 ${f(x2(L,Q))}`);W.push(G?l0($G(G),"diff"):"_无 diff 内容_")}if(Y.length>V.length)W.push(""),W.push(`还有 ${Y.length-V.length} 个文件未展开显示。`);if(J)W.push(""),W.push(J);return W.join(`
72
+ `)}function U$($){return String($?.file_path??$?.path??$?.notebook_path??"")}function JG($){let Z=U$($),J=[$?.offset!=null?`offset ${$.offset}`:"",$?.limit!=null?`limit ${$.limit}`:""].filter(Boolean).join(" · ");return J&&Z?`${Z} · ${J}`:Z}function YG($){let Z=U$($),J=typeof $?.content==="string"?$.content:"",Y=J?J.split(/\r?\n/).length:0;return Z&&Y?`${Z} · ${Y} 行`:Z}function QG($){let Z=U$($),J=$?.replace_all?"全局替换":"替换";return Z?`${J} ${Z}`:J}function WG($){let Z=U$($),J=Array.isArray($?.edits)?$.edits.length:0,Y=J?` · ${J} 处`:"";return Z?`批量编辑 ${Z}${Y}`:`批量编辑${Y}`}function HG($,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 TJ($){switch($){case"pending":return"待办";case"in_progress":return"进行中";case"completed":return"完成";default:return String($??"未知")}}function XG($){let Z=Array.isArray($?.todos)?$.todos:[];if(Z.length===0)return"";let J=new Map;for(let Q of Z){let W=TJ(Q?.status);J.set(W,(J.get(W)??0)+1)}let Y=[...J.entries()].map(([Q,W])=>`${Q} ${W}`).join(" · ");return`${Z.length} 项${Y?` · ${Y}`:""}`}function VG($){let Z=String($?.url??""),J=typeof $?.prompt==="string"?$.prompt.trim():"";return Z&&J?`${Z} · ${J}`:Z||J}function v1($,Z){if(Z==null)return;$.push(""),$.push("---"),$.push("**结果**"),$.push(X$(Z,1200))}function NJ($,Z,J){let Y=[],Q=U$($);if(Q)Y.push(`**路径**: ${f(Q)}`);if($?.offset!=null)Y.push(`**offset**: ${f($.offset)}`);if($?.limit!=null)Y.push(`**limit**: ${f($.limit)}`);if(J)Y.push(""),Y.push(J);if(Z!=null)Y.push(""),Y.push("_内容已读取,未展开到群聊卡片。_");return Y.length>0?Y.join(`
73
+ `):w0($??{},2000)}function kJ($,Z,J){let Y=[],Q=U$($),W=typeof $?.content==="string"?$.content:"";if(Q)Y.push(`**路径**: ${f(Q)}`);if(W){let H=W.split(/\r?\n/).length;Y.push(`**内容**: ${H} 行 / ${W.length} 字符`),Y.push(X$(W,1200))}if(J)Y.push(""),Y.push(J);return v1(Y,Z),Y.length>0?Y.join(`
74
+ `):w0($??{},2000)}function SJ($,Z,J){let Y=[],Q=U$($);if(Q)Y.push(`**路径**: ${f(Q)}`);if($?.cell_id)Y.push(`**cell**: ${f($.cell_id)}`);if($?.edit_mode)Y.push(`**模式**: ${f($.edit_mode)}`);if($?.replace_all)Y.push("**范围**: 全局替换");if(typeof $?.old_string==="string")Y.push(""),Y.push("**查找**"),Y.push(X$($.old_string,800));let W=typeof $?.new_string==="string"?$.new_string:typeof $?.new_source==="string"?$.new_source:"";if(W)Y.push(""),Y.push("**替换为**"),Y.push(X$(W,800));if(J)Y.push(""),Y.push(J);return v1(Y,Z),Y.length>0?Y.join(`
75
+ `):w0($??{},2000)}function yJ($,Z,J){let Y=[],Q=U$($),W=Array.isArray($?.edits)?$.edits:[];if(Q)Y.push(`**路径**: ${f(Q)}`);Y.push(`**编辑**: ${W.length} 处`);for(let[H,X]of W.slice(0,5).entries()){if(Y.push(""),Y.push(`**#${H+1}${X?.replace_all?" · 全局替换":""}**`),typeof X?.old_string==="string")Y.push("查找:"),Y.push(X$(X.old_string,500));if(typeof X?.new_string==="string")Y.push("替换为:"),Y.push(X$(X.new_string,500))}if(W.length>5)Y.push(""),Y.push(`还有 ${W.length-5} 处编辑未展开显示。`);if(J)Y.push(""),Y.push(J);return v1(Y,Z),Y.join(`
76
+ `)}function xJ($,Z,J,Y){let Q=[];if($==="Glob"){if(Q.push("**动作**: 匹配文件"),Z?.pattern)Q.push(`**pattern**: ${f(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${f(Z.path)}`)}else if($==="Grep"){if(Q.push("**动作**: 搜索文件"),Z?.pattern)Q.push(`**pattern**: ${f(Z.pattern)}`);if(Z?.path)Q.push(`**path**: ${f(Z.path)}`);if(Z?.glob)Q.push(`**glob**: ${f(Z.glob)}`);if(Z?.type)Q.push(`**type**: ${f(Z.type)}`);if(Z?.output_mode)Q.push(`**output**: ${f(Z.output_mode)}`)}else{if(Q.push("**动作**: 列目录"),Z?.path)Q.push(`**path**: ${f(Z.path)}`);if(Array.isArray(Z?.ignore)&&Z.ignore.length)Q.push(`**ignore**: ${Z.ignore.map(f).join(" ")}`)}if(Y)Q.push(""),Q.push(Y);return v1(Q,J),Q.join(`
77
+ `)}function bJ($,Z,J){let Y=Array.isArray($?.todos)?$.todos:[],Q=[`**待办**: ${Y.length} 项`];for(let W of Y.slice(0,12)){let H=TJ(W?.status),X=String(W?.content??W?.activeForm??"").trim()||"(空)";Q.push(`- ${H}: ${X}`)}if(Y.length>12)Q.push(`- 还有 ${Y.length-12} 项未显示`);if(J)Q.push(""),Q.push(J);return v1(Q,Z),Q.join(`
78
+ `)}function q8($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function L8($,Z){return q8(Z)??$?.action??{}}function P8($,Z){let J=L8($,Z),Y=Array.isArray(J?.queries)?J.queries.filter((W)=>typeof W==="string"&&W.length>0):[],Q=typeof J?.query==="string"&&J.query.length>0?J.query:typeof $?.query==="string"&&$.query.length>0?$.query:"";return Y.length>0?Y:Q?[Q]:[]}function j8($,Z){let J=L8($,Z);return String(J?.url??$?.url??"")}function CJ($){let Z=P8($,null);if(Z.length===1)return Z[0];if(Z.length>1)return`${Z.length} 条查询 · ${Z[0]}`;let J=j8($,null);if(J)return J;let Y=$?.action?.type;return typeof Y==="string"&&Y!=="other"?Y:""}function zG($,Z){let J=P8($,Z);if(J.length===1)return J[0];if(J.length>1)return`${J.length} 条查询 · ${J[0]}`;let Y=j8($,Z);if(Y)return Y;return CJ($)}function wJ($,Z,J){let Y=L8($,Z),Q=P8($,Z),W=j8($,Z),H=[],X=typeof Y?.type==="string"?Y.type:"";if(X==="search"||Q.length>0){if(H.push("**动作**: 搜索"),Q.length>0){H.push(""),H.push("**查询**");for(let V of Q.slice(0,6))H.push(`- ${f(V)}`);if(Q.length>6)H.push(`- 还有 ${Q.length-6} 条未显示`)}}else if(X==="open_page"){if(H.push("**动作**: 打开页面"),W)H.push(`**URL**: ${f(W)}`)}else if(X==="find_in_page"){if(H.push("**动作**: 页内查找"),W)H.push(`**URL**: ${f(W)}`);if(Y?.pattern)H.push(`**关键词**: ${f(Y.pattern)}`)}else if(H.push(`**动作**: ${X?f(X):"网页搜索"}`),W)H.push(`**URL**: ${f(W)}`);if(J)H.push(""),H.push(J);if(H.length===1&&!Q.length&&!W&&Z!=null)H.push(""),H.push("---"),H.push("**output:**"),H.push(l0(Z.slice(0,3000),"json"));return H.join(`
79
+ `)}function fJ($,Z,J){let Y=["**动作**: 读取网页"];if($?.url)Y.push(`**URL**: ${f($.url)}`);if($?.prompt)Y.push(""),Y.push("**问题**"),Y.push(String($.prompt).slice(0,1200));if(J)Y.push(""),Y.push(J);return v1(Y,Z),Y.join(`
80
+ `)}function GG($){let Z=String($?.server??""),J=String($?.tool??""),Y=Z&&J?`${Z}.${J}`:J||Z,Q=C2($?.arguments);return Q&&Y?`${Y}: ${Q}`:Y||Q}function vJ($,Z,J){let Y=[];if($?.server)Y.push(`**server**: ${f($.server)}`);if($?.tool)Y.push(`**tool**: ${f($.tool)}`);let Q=$?.arguments;if(Q&&typeof Q==="object"&&Object.keys(Q).length>0){if(Y.length>0)Y.push("");Y.push("**arguments**"),Y.push(w0(Q,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){let W=q8(Z);if(Y.push(""),Y.push("---"),Y.push("**结果**"),W&&Array.isArray(W.content)){let H=W.content.map((X)=>typeof X?.text==="string"?X.text:"").filter(Boolean);if(H.length>0)Y.push(H.join(`
81
+ `).slice(0,3000));if(W.structuredContent)Y.push(""),Y.push("**structuredContent**"),Y.push(w0(W.structuredContent,2000));if(H.length===0&&!W.structuredContent)Y.push(w0(W,3000))}else Y.push(W?w0(W,3000):l0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
82
+ `):w0($??{},2000)}function AG($,Z,J,Y){let Q=["**类型**: 模型服务端内置工具",`**tool**: ${f(typeof Z?.tool==="string"&&Z.tool?Z.tool:LJ($))}`],W=Z?.input;if(W&&typeof W==="object")if(Q.push(""),Q.push("**input**"),Object.keys(W).length>0)Q.push(w0(W,2000));else Q.push("_provider 未提供结构化 input_");else if(W!=null&&W!=="")Q.push(`**input**: ${f(W)}`);if(Y)Q.push(""),Q.push(Y);if(J!=null)Q.push(""),Q.push("---"),Q.push("**结果**"),Q.push(X$(J,3000));return Q.join(`
83
+ `)}function _G($){let Z=typeof $?.revisedPrompt==="string"?$.revisedPrompt:"",J=typeof $?.status==="string"?$.status:"";return Z||J}function hJ($,Z,J){let Y=[];if($?.status)Y.push(`**状态**: ${f($.status)}`);if($?.revisedPrompt){if(Y.length>0)Y.push("");Y.push("**提示词**"),Y.push(String($.revisedPrompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null&&Z.trim())Y.push(""),Y.push("---"),Y.push("**输出**"),Y.push(f(Z.trim()));return Y.length>0?Y.join(`
84
+ `):w0($??{},2000)}function KG($){let Z=typeof $?.tool==="string"?$.tool:"",J=typeof $?.prompt==="string"?$.prompt:"",Y=typeof $?.description==="string"?$.description:"",Q=typeof $?.subject==="string"?$.subject:"",W=Y||Q||J;return Z&&W?`${Z}: ${W}`:W||Z}function Z9($,Z,J){let Y=[];if($?.tool)Y.push(`**tool**: ${f($.tool)}`);if($?.model)Y.push(`**model**: ${f($.model)}`);if($?.description)Y.push(`**描述**: ${$.description}`);if($?.subagent_type)Y.push(`**类型**: ${f($.subagent_type)}`);if($?.prompt){if(Y.length>0)Y.push("");Y.push("**prompt**"),Y.push(String($.prompt).slice(0,2000))}if(J)Y.push(""),Y.push(J);if(Z!=null){Y.push(""),Y.push("---"),Y.push("**状态**");let Q=q8(Z);Y.push(Q?w0(Q,3000):l0(Z.slice(0,3000)))}return Y.length>0?Y.join(`
85
+ `):w0($??{},2000)}function O$($,Z,J,Y,Q="⏳",W){let H=b2(Z)&&Y!=null?zG(J,Y):F$(Z,J),X=H.length>80?H.slice(0,80)+"…":H,V=r$(Z),z=X?`${Q} \uD83D\uDD27 ${V}: ${X}`:`${Q} \uD83D\uDD27 ${V}`,G=W?`
86
+
87
+ ${W}`:"",_=J9(Z)?RJ(J,Y,W):Y9(Z)?DJ(J,Y,W):K9(Z)?AG(Z,J,Y,W):Q9(Z)?EJ(J,Y,W):b2(Z)?wJ(J,Y,W):W9(Z)?fJ(J,Y,W):_8(Z)?vJ(J,Y,W):H9(Z)?hJ(J,Y,W):X9(Z)?NJ(J,Y,W):V9(Z)?kJ(J,Y,W):z9(Z)?SJ(J,Y,W):G9(Z)?yJ(J,Y,W):B8(Z)?xJ(Z,J,Y,W):A9(Z)?bJ(J,Y,W):_9(Z)?Z9({prompt:C2(J)||"提交计划"},Y,W):K8(Z)?Z9(J,Y,W):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```"+G+(Y!=null?`
88
88
  ---
89
89
  **output:**
90
90
  \`\`\`
91
- `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:z}},expanded:!1,elements:[{tag:"markdown",content:s(K)}]}}function k2($,Z){let J=Z.length,Y=Z.some((V)=>V.isError),Q=Z.every((V)=>V.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let V=s3(Z[0]);return V?`${W} \uD83D\uDD27 编辑文件: ${V}`:`${W} \uD83D\uDD27 编辑文件`})():`${W} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((V)=>{let z=s3(V);return z?`\`${z}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:s(X.join(`
92
- `))}]}}function s3($){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 S2($,Z){let J=Z.length,Y=Z.some((V)=>V.isError),Q=Z.every((V)=>V.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let V=j0("Read",Z[0]?.input);return V?`${W} \uD83D\uDD27 Read: ${V}`:`${W} \uD83D\uDD27 Read`})():`${W} \uD83D\uDD27 Read · ${J} 次`,X=Z.map((V)=>`\`${String(V.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:s(X.join(`
93
- `))}]}}function W7($,Z,J,Y){let Q=j0(Z,J),W=n0(Z),H=Q?`\uD83D\uDD10 等审批 · ${W}: ${Q}`:`\uD83D\uDD10 等审批 · ${W}`,X=d4(Z)?YJ(J,null):n4(Z)?QJ(J,null):a4(Z)?zJ(J,null):T2(Z)?PJ(J,null):o4(Z)?DJ(J,null):s8(Z)?jJ(J,null):r4(Z)?MJ(J,null):t4(Z)?AJ(J,null):s4(Z)?KJ(J,null):e4(Z)?_J(J,null):$6(Z)?BJ(J,null):$7(Z)?qJ(Z,J,null):Z6(Z)?RJ(J,null):J6(Z)?i4({prompt:N2(J)||"提交计划"},null):e8(Z)?i4(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[n8("✅ 允许","primary",Y,"allow"),n8("♾️ 始终允许","default",Y,"allow_always"),n8("❌ 拒绝","danger",Y,"deny")]}]}}function n8($,Z,J,Y){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Y}}]}]}}var Cz=300,e3="server_tool:";var FJ=S(()=>{S$();X4()});import{execFile as sz}from"node:child_process";import{readFileSync as H7,statfsSync as ez,statSync as UJ}from"node:fs";import{cpus as $G,homedir as ZG}from"node:os";import{promisify as JG}from"node:util";function QG(){try{let $=H7("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:$G().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return G(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function WG(){try{let $=H7("/proc/meminfo","utf8"),Z=(W)=>{let H=$.match(new RegExp(`^${W}:\\s+(\\d+)\\s*kB`,"m"));return H?parseInt(H[1],10)*1024:0},J=Z("MemTotal"),Y=Z("MemAvailable");if(!J)return null;let Q=Math.max(0,J-Y);return{totalBytes:J,availBytes:Y,usedBytes:Q,percent:Math.round(Q/J*100)}}catch($){return G(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function OJ($,Z){try{let J=ez(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,W=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:W,percent:Math.round(W/Y*100)}}catch(J){return G(`sysinfo: statfs ${Z} failed: ${J}`),null}}function HG(){let $=[],Z=OJ("/","/");if(Z)$.push(Z);let J=ZG();if(J&&J!=="/"){let Y=!1;try{let Q=UJ("/"),W=UJ(J);Y=Q.dev===W.dev}catch{}if(!Y){let Q=OJ("$HOME",J);if(Q)$.push(Q)}}return $}function XG(){try{let $=H7("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function EJ($,Z=2000){try{let{stdout:J}=await YG("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return G(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function TJ($){return NJ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function VG(){let $=await EJ(["list-units","--type=service","--all","--no-legend","--plain",...NJ.map((V)=>`${V}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
94
- `).map((V)=>V.trim()).filter((V)=>V.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let V of Z){let A=V.replace(/^●\s*/,"").split(/\s+/)[0];if(!A)continue;if(!TJ(A))continue;J.push(A)}if(J.length===0)return{services:[],error:null};let Y=await EJ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=XG(),W=Y.split(/\n\s*\n/),H=[],X=(V)=>{let z=parseInt(V??"0",10);if(z<=0||Q===null)return null;return Math.max(0,Q-z/1e6)};for(let V of W){let z={};for(let K of V.split(`
95
- `)){let B=K.indexOf("=");if(B<=0)continue;z[K.slice(0,B)]=K.slice(B+1)}let A=z.Id??"";if(!TJ(A))continue;H.push({name:A.replace(/\.service$/,""),active:z.ActiveState??"unknown",sub:z.SubState??"",lastActiveAgoSec:X(z.ActiveEnterTimestampMonotonic),stateAgoSec:X(z.StateChangeTimestampMonotonic)})}return H.sort((V,z)=>V.name.localeCompare(z.name)),{services:H,error:null}}async function kJ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=QG(),Z=WG(),J=HG(),{services:Y,error:Q}=await VG();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var YG,NJ,y2="cc-* / codex-*";var X7=S(()=>{g();YG=JG(sz),NJ=["cc-","codex-"]});function C2($,Z){return Z}function V7($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:M.footer,content:C2($.title,$.status)}]}}}function SJ($){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 zG($){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 x2($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Y=Z%60;if(J<24)return`${J}h ${Y}m`;return`${Math.floor(J/24)}d ${J%24}h`}function V0($){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 xJ($){if($===void 0)return"**\uD83D\uDCCA 订阅额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA Codex 额度** 未登录 ChatGPT — 运行 `codex login`";case"auth_failed":return"**\uD83D\uDCCA Codex 额度** 当前不是 ChatGPT 登录 — 请运行 `codex login`";case"rate_limited":return"**\uD83D\uDCCA Codex 额度** API 429 限流,稍后重试";case"network":return`**\uD83D\uDCCA Codex 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let J=[$.subscriptionType?`**\uD83D\uDCCA Codex 额度** · ChatGPT ${$.subscriptionType}`:"**\uD83D\uDCCA Codex 额度**"];if($.fiveHour){let Y=[b1($.fiveHour.percent)];if($.fiveHour.resetsAt)Y.push(`重置 ${V0($.fiveHour.resetsAt)}`);J.push(` · ${yJ($.fiveHour.durationMins,"主窗口")} ${Y.join(" · ")}`)}if($.weekly){let Y=[b1($.weekly.percent)];if($.weekly.resetsAt)Y.push(`重置 ${V0($.weekly.resetsAt)}`);J.push(` · ${yJ($.weekly.durationMins,"次窗口")} ${Y.join(" · ")}`)}return J.length===1?"**\uD83D\uDCCA Codex 额度** _无数据_":J.join(`
96
- `)}function KG($){if($===void 0)return"**\uD83D\uDCCA GLM 额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA GLM 额度** 未配置 `ANTHROPIC_AUTH_TOKEN` — 检查 ~/.claude/settings.json";case"not_glm":return"**\uD83D\uDCCA GLM 额度** 非 GLM 后端 — ANTHROPIC_BASE_URL 不是 bigmodel / z.ai";case"rate_limited":return"**\uD83D\uDCCA GLM 额度** API 限流,稍后重试";case"network":return`**\uD83D\uDCCA GLM 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let Z=$.level?$.level.charAt(0).toUpperCase()+$.level.slice(1):"",Y=[Z?`**\uD83D\uDCCA GLM 额度** · ${Z} 套餐`:"**\uD83D\uDCCA GLM 额度**"];if($.fiveHour){let Q=[b1($.fiveHour.percent)];if($.fiveHour.resetsAt)Q.push(`重置 ${V0($.fiveHour.resetsAt)}`);Y.push(` · 5h 窗口 ${Q.join(" · ")}`)}if($.weekly){let Q=[b1($.weekly.percent)];if($.weekly.resetsAt)Q.push(`重置 ${V0($.weekly.resetsAt)}`);Y.push(` · 周额度 ${Q.join(" · ")}`)}if($.monthly){let Q=[b1($.monthly.percent)];if(typeof $.monthly.used==="number"&&typeof $.monthly.total==="number")Q.push(`${$.monthly.used}/${$.monthly.total}`);if($.monthly.resetsAt)Q.push(`重置 ${V0($.monthly.resetsAt)}`);Y.push(` · 月度工具 ${Q.join(" · ")}`)}return Y.length===1?"**\uD83D\uDCCA GLM 额度** _无数据_":Y.join(`
97
- `)}function b1($){return typeof $==="number"&&Number.isFinite($)?`${Math.round($)}%`:"MISS"}function yJ($,Z){if(!$||$<=0)return Z;if($%1440===0)return`${$/1440}d`;if($%60===0)return`${$/60}h`;return`${$}m`}function BG($){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 qG($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${y2} _n/a_`].join(`
98
- `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:W}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${W.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${SJ($.mem.usedBytes)}/${SJ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${y2} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${y2} _无_`);else{Z.push(`**服务** ${y2} (${$.services.length})`);for(let J of $.services){let Y=_G[J.active]??"·",Q=J.lastActiveAgoSec,W=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(W!=null)H.push(`已运行 ${x2(W*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${x2(Q*1000)}前`);else H.push("从未启动");if(W!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${x2(W*1000)}`)}}else if(W!=null)H.push(`已 ${x2(W*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
99
- `)}function RG($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=GG[J.status]??"·",Q=AG[J.status]??J.status,W=J.uptimeMs!=null&&J.uptimeMs>0?` · ${x2(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"";return` · ${Y} \`${J.name}\` · ${Q}${W}${H}`}).join(`
100
- `)}function Q6($,Z=M.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:RG($)}]}}function LG($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${B7($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
101
- `)}function W6($,Z=M.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:LG($)}}function H6($,Z=M.consoleHost){let J=BG($);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:qG($)}]}}function PG($){if($===void 0)return"**\uD83D\uDCCA 额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA 额度** 未配置凭据 — 检查 config.toml [token_source.*]";case"not_applicable":return"**\uD83D\uDCCA 额度** —(该来源无额度查询)";case"rate_limited":return"**\uD83D\uDCCA 额度** API 限流,稍后重试";case"network":return`**\uD83D\uDCCA 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let J=[$.planLabel?`**\uD83D\uDCCA 额度** · ${$.planLabel}`:"**\uD83D\uDCCA 额度**"];for(let Y of $.windows){let Q=[b1(Y.percent)];if(typeof Y.used==="number"&&typeof Y.total==="number")Q.push(`${Y.used}/${Y.total}`);if(Y.resetsAt)Q.push(`重置 ${V0(Y.resetsAt)}`);J.push(` · ${Y.label} ${Q.join(" · ")}`)}return J.length===1&&!$.planLabel?"**\uD83D\uDCCA 额度** _无数据_":J.join(`
102
- `)}function b2($){let Z=$.unifiedUsage!==void 0?PG($.unifiedUsage):$.provider==="claude"?KG($.glmUsage):xJ($.usage);return{tag:"markdown",element_id:M.consoleUsage,content:Z}}function CJ($,Z){return[W6($,Z),Q6($),H6($.sysinfo),b2($)]}function z7($){let{sessionName:Z,status:J}=$,Y=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Y},body:{elements:CJ($)}}}function G7($){return f1($.sessionName,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${a0($.currentDisplay??"未选择")}
103
- 选账号进入模型选择。`},...$.providers.map((Z)=>DG(Z,$.panelId))]})}function DG($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${r$($.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=[$.selected?"当前账号":"",`${$.modelCount} 个模型`].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${r$($.display)}**
104
- ${J}`}]},{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 A7($){return f1($.sessionName,bJ($))}function K7($){return f1($.sessionName,G6($))}function X6($){return f1($.sessionName,fJ($),"green")}function f1($,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 bJ($){let Z=MG($.models,$.panelId);return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${wJ($.currentModel,$.currentEffort)}`,"选模型进入 effort 选择。"].join(`
105
- `)},...$.models.length?Z:[{tag:"markdown",content:"_未返回可用模型列表_"}],{tag:"button",text:{tag:"plain_text",content:"➕ 补录模型"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_custom_prompt",panel_id:$.panelId,...$.models[0]?.sourceId?{source_id:$.models[0].sourceId}:{}}}]}]}}function V6($,Z="cancelled"){return f1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function _7($,Z,J){return f1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**(列表外的模型,端点会先校验真伪)`,"_裸词命令(hi/stop/model 等)不受影响_"].join(`
106
- `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function z6($,Z,J){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function G6($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${OG($.model)}`,`当前: ${wJ($.currentModel,$.currentEffort)}`].join(`
107
- `)},...$.model.efforts.length?$.model.efforts.map((Z)=>FG($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function fJ($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",a0(vJ($.model,$.effort,$.provider)),r$($.scope)].join(`
108
- `)}]}}function jG($,Z){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${r$($.displayName)}** · 未配置
109
- ${r$($.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 J=$.displayName&&$.displayName!==$.model?`**${r$($.displayName)}**`:`**${a0($.model)}**`,Y=[$.isDefault?`${B7($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),Q=$.description?`
110
- `+r$(EG($.description,110)):"";return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[J,a0($.model),Y.length?Y.join(" · "):""].filter(Boolean).join(`
111
- `)+Q}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:UG($,Z)}]}]}]}]}function MG($,Z){let J=[{title:"Codex",models:$.filter((W)=>(W.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((W)=>W.provider==="claude")}].filter((W)=>W.models.length>0),Y=(W)=>W.flatMap((H)=>jG(H,Z));if(J.length<=1)return Y($);let Q=[];for(let W of J)Q.push({tag:"markdown",content:`**${W.title}**`}),Q.push(...Y(W.models));return Q}function FG($,Z,J,Y,Q){let W=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",W?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${r$(Z.effort)}**`,H,Z.description?r$(Z.description):""].filter(Boolean).join(`
112
- `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:W?"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 UG($,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 OG($){return $.displayName&&$.displayName!==$.model?`${r$($.displayName)} (${a0($.model)})`:a0($.model)}function wJ($,Z){return a0(vJ($,Z))}function vJ($,Z,J){let Y=J&&J!=="codex"?`${B7(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function B7($){return $==="claude"?"Claude":"Codex"}function EG($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function r$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function a0($){return"`"+$.replace(/`/g,"\\`")+"`"}function z0($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec)Z.push(`⏱ ${$.durationSec}s`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${zG($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var GG,AG,_G;var hJ=S(()=>{X7();S$();GG={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},AG={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"};_G={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function q7($){let Z=kG($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:TG($.notice)},body:{elements:[...$.notice?[NG($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(SG)]}}}function TG($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function NG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
91
+ `+Y.slice(0,3000)+"\n```":"");return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:z}},expanded:!1,elements:[{tag:"markdown",content:d(_)}]}}function w2($,Z){let J=Z.length,Y=Z.some((V)=>V.isError),Q=Z.every((V)=>V.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let V=BJ(Z[0]);return V?`${W} \uD83D\uDD27 编辑文件: ${V}`:`${W} \uD83D\uDD27 编辑文件`})():`${W} \uD83D\uDD27 编辑文件 · ${J} 次`,X=Z.map((V)=>{let z=BJ(V);return z?`\`${z}\``:"`(无 path)`"});return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:d(X.join(`
92
+ `))}]}}function BJ($){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 f2($,Z){let J=Z.length,Y=Z.some((V)=>V.isError),Q=Z.every((V)=>V.output!==null),W=Y?"❌":Q?"✅":"⏳",H=J===1?(()=>{let V=F$("Read",Z[0]?.input);return V?`${W} \uD83D\uDD27 Read: ${V}`:`${W} \uD83D\uDD27 Read`})():`${W} \uD83D\uDD27 Read · ${J} 次`,X=Z.map((V)=>`\`${String(V.input.file_path??"(无 path)")}\``);return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:d(X.join(`
93
+ `))}]}}function R8($,Z,J,Y){let Q=F$(Z,J),W=r$(Z),H=Q?`\uD83D\uDD10 等审批 · ${W}: ${Q}`:`\uD83D\uDD10 等审批 · ${W}`,X=J9(Z)?RJ(J,null):Y9(Z)?DJ(J,null):Q9(Z)?EJ(J,null):b2(Z)?wJ(J,null):W9(Z)?fJ(J,null):_8(Z)?vJ(J,null):H9(Z)?hJ(J,null):X9(Z)?NJ(J,null):V9(Z)?kJ(J,null):z9(Z)?SJ(J,null):G9(Z)?yJ(J,null):B8(Z)?xJ(Z,J,null):A9(Z)?bJ(J,null):_9(Z)?Z9({prompt:C2(J)||"提交计划"},null):K8(Z)?Z9(J,null):"```\n"+JSON.stringify(J??{},null,2).slice(0,2000)+"\n```";return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!0,elements:[{tag:"markdown",content:X},{tag:"column_set",columns:[X8("✅ 允许","primary",Y,"allow"),X8("♾️ 始终允许","default",Y,"allow_always"),X8("❌ 拒绝","danger",Y,"deny")]}]}}function X8($,Z,J,Y){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:Z,behaviors:[{type:"callback",value:{kind:"permission",request_id:J,decision:Y}}]}]}}var az=300,qJ="server_tool:";var gJ=N(()=>{y0();L4()});import{execFile as BG}from"node:child_process";import{readFileSync as D8,statfsSync as qG,statSync as IJ}from"node:fs";import{cpus as LG,homedir as PG}from"node:os";import{promisify as jG}from"node:util";function DG(){try{let $=D8("/proc/loadavg","utf8").trim().split(/\s+/);return{cores:LG().length,load1:parseFloat($[0]??"0"),load5:parseFloat($[1]??"0"),load15:parseFloat($[2]??"0")}}catch($){return A(`sysinfo: read /proc/loadavg failed: ${$}`),null}}function MG(){try{let $=D8("/proc/meminfo","utf8"),Z=(W)=>{let H=$.match(new RegExp(`^${W}:\\s+(\\d+)\\s*kB`,"m"));return H?parseInt(H[1],10)*1024:0},J=Z("MemTotal"),Y=Z("MemAvailable");if(!J)return null;let Q=Math.max(0,J-Y);return{totalBytes:J,availBytes:Y,usedBytes:Q,percent:Math.round(Q/J*100)}}catch($){return A(`sysinfo: read /proc/meminfo failed: ${$}`),null}}function cJ($,Z){try{let J=qG(Z,{bigint:!1}),Y=J.blocks*J.bsize,Q=J.bavail*J.bsize,W=Math.max(0,Y-Q);if(!Y)return null;return{label:$,path:Z,totalBytes:Y,availBytes:Q,usedBytes:W,percent:Math.round(W/Y*100)}}catch(J){return A(`sysinfo: statfs ${Z} failed: ${J}`),null}}function FG(){let $=[],Z=cJ("/","/");if(Z)$.push(Z);let J=PG();if(J&&J!=="/"){let Y=!1;try{let Q=IJ("/"),W=IJ(J);Y=Q.dev===W.dev}catch{}if(!Y){let Q=cJ("$HOME",J);if(Q)$.push(Q)}}return $}function UG(){try{let $=D8("/proc/uptime","utf8").trim().split(/\s+/);return parseFloat($[0]??"0")}catch{return null}}async function mJ($,Z=2000){try{let{stdout:J}=await RG("systemctl",["--user",...$],{timeout:Z,maxBuffer:4194304});return J}catch(J){return A(`sysinfo: systemctl ${$.join(" ")} failed: ${J}`),null}}function uJ($){return pJ.some((Z)=>$.startsWith(Z))&&$.endsWith(".service")}async function OG(){let $=await mJ(["list-units","--type=service","--all","--no-legend","--plain",...pJ.map((V)=>`${V}*`)]);if($===null)return{services:[],error:"systemctl 不可用"};let Z=$.split(`
94
+ `).map((V)=>V.trim()).filter((V)=>V.length>0);if(Z.length===0)return{services:[],error:null};let J=[];for(let V of Z){let G=V.replace(/^●\s*/,"").split(/\s+/)[0];if(!G)continue;if(!uJ(G))continue;J.push(G)}if(J.length===0)return{services:[],error:null};let Y=await mJ(["show",...J,"-p","Id","-p","ActiveState","-p","SubState","-p","ActiveEnterTimestampMonotonic","-p","StateChangeTimestampMonotonic"]);if(Y===null)return{services:[],error:"systemctl show 失败"};let Q=UG(),W=Y.split(/\n\s*\n/),H=[],X=(V)=>{let z=parseInt(V??"0",10);if(z<=0||Q===null)return null;return Math.max(0,Q-z/1e6)};for(let V of W){let z={};for(let _ of V.split(`
95
+ `)){let B=_.indexOf("=");if(B<=0)continue;z[_.slice(0,B)]=_.slice(B+1)}let G=z.Id??"";if(!uJ(G))continue;H.push({name:G.replace(/\.service$/,""),active:z.ActiveState??"unknown",sub:z.SubState??"",lastActiveAgoSec:X(z.ActiveEnterTimestampMonotonic),stateAgoSec:X(z.StateChangeTimestampMonotonic)})}return H.sort((V,z)=>V.name.localeCompare(z.name)),{services:H,error:null}}async function lJ(){if(process.platform==="win32")return{cpu:null,mem:null,disks:[],services:[],servicesError:"Windows: sysinfo 暂未支持"};let $=DG(),Z=MG(),J=FG(),{services:Y,error:Q}=await OG();return{cpu:$,mem:Z,disks:J,services:Y,servicesError:Q}}var RG,pJ,v2="cc-* / codex-*";var M8=N(()=>{I();RG=jG(BG),pJ=["cc-","codex-"]});function g2($,Z){return Z}function F8($){return{schema:"2.0",config:{update_multi:!0,streaming_mode:!0,summary:{content:$.status}},body:{elements:[{tag:"markdown",element_id:M.footer,content:g2($.title,$.status)}]}}}function iJ($){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 EG($){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 h2($){if($<60000)return`${Math.round($/1000)}s`;let Z=Math.floor($/60000);if(Z<60)return`${Z}m`;let J=Math.floor(Z/60),Y=Z%60;if(J<24)return`${J}h ${Y}m`;return`${Math.floor(J/24)}d ${J%24}h`}function V$($){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 nJ($){if($===void 0)return"**\uD83D\uDCCA 订阅额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA Codex 额度** 未登录 ChatGPT — 运行 `codex login`";case"auth_failed":return"**\uD83D\uDCCA Codex 额度** 当前不是 ChatGPT 登录 — 请运行 `codex login`";case"rate_limited":return"**\uD83D\uDCCA Codex 额度** API 429 限流,稍后重试";case"network":return`**\uD83D\uDCCA Codex 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let J=[$.subscriptionType?`**\uD83D\uDCCA Codex 额度** · ChatGPT ${$.subscriptionType}`:"**\uD83D\uDCCA Codex 额度**"];if($.fiveHour){let Y=[h1($.fiveHour.percent)];if($.fiveHour.resetsAt)Y.push(`重置 ${V$($.fiveHour.resetsAt)}`);J.push(` · ${dJ($.fiveHour.durationMins,"主窗口")} ${Y.join(" · ")}`)}if($.weekly){let Y=[h1($.weekly.percent)];if($.weekly.resetsAt)Y.push(`重置 ${V$($.weekly.resetsAt)}`);J.push(` · ${dJ($.weekly.durationMins,"次窗口")} ${Y.join(" · ")}`)}return J.length===1?"**\uD83D\uDCCA Codex 额度** _无数据_":J.join(`
96
+ `)}function kG($){if($===void 0)return"**\uD83D\uDCCA GLM 额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA GLM 额度** 未配置 `ANTHROPIC_AUTH_TOKEN` — 检查 ~/.claude/settings.json";case"not_glm":return"**\uD83D\uDCCA GLM 额度** 非 GLM 后端 — ANTHROPIC_BASE_URL 不是 bigmodel / z.ai";case"rate_limited":return"**\uD83D\uDCCA GLM 额度** API 限流,稍后重试";case"network":return`**\uD83D\uDCCA GLM 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let Z=$.level?$.level.charAt(0).toUpperCase()+$.level.slice(1):"",Y=[Z?`**\uD83D\uDCCA GLM 额度** · ${Z} 套餐`:"**\uD83D\uDCCA GLM 额度**"];if($.fiveHour){let Q=[h1($.fiveHour.percent)];if($.fiveHour.resetsAt)Q.push(`重置 ${V$($.fiveHour.resetsAt)}`);Y.push(` · 5h 窗口 ${Q.join(" · ")}`)}if($.weekly){let Q=[h1($.weekly.percent)];if($.weekly.resetsAt)Q.push(`重置 ${V$($.weekly.resetsAt)}`);Y.push(` · 周额度 ${Q.join(" · ")}`)}if($.monthly){let Q=[h1($.monthly.percent)];if(typeof $.monthly.used==="number"&&typeof $.monthly.total==="number")Q.push(`${$.monthly.used}/${$.monthly.total}`);if($.monthly.resetsAt)Q.push(`重置 ${V$($.monthly.resetsAt)}`);Y.push(` · 月度工具 ${Q.join(" · ")}`)}return Y.length===1?"**\uD83D\uDCCA GLM 额度** _无数据_":Y.join(`
97
+ `)}function h1($){return typeof $==="number"&&Number.isFinite($)?`${Math.round($)}%`:"MISS"}function dJ($,Z){if(!$||$<=0)return Z;if($%1440===0)return`${$/1440}d`;if($%60===0)return`${$/60}h`;return`${$}m`}function yG($){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 xG($){if(!$)return["**负载** _n/a_","**内存** _n/a_",`**服务** ${v2} _n/a_`].join(`
98
+ `);let Z=[];if($.cpu){let{cores:J,load1:Y,load5:Q,load15:W}=$.cpu;Z.push(`**负载** ${Y.toFixed(2)} / ${Q.toFixed(2)} / ${W.toFixed(2)} (${J}核)`)}else Z.push("**负载** _n/a_");if($.mem)Z.push(`**内存** ${$.mem.percent}% (${iJ($.mem.usedBytes)}/${iJ($.mem.totalBytes)})`);else Z.push("**内存** _n/a_");if($.servicesError)Z.push(`**服务** ${v2} _${$.servicesError}_`);else if($.services.length===0)Z.push(`**服务** ${v2} _无_`);else{Z.push(`**服务** ${v2} (${$.services.length})`);for(let J of $.services){let Y=SG[J.active]??"·",Q=J.lastActiveAgoSec,W=J.stateAgoSec,H=[J.active];if(J.active==="active"){if(W!=null)H.push(`已运行 ${h2(W*1000)}`)}else if(J.active==="inactive"||J.active==="failed"){if(Q!=null)H.push(`上次活跃 ${h2(Q*1000)}前`);else H.push("从未启动");if(W!=null){let X=J.active==="failed"?"已挂":"已停";H.push(`${X} ${h2(W*1000)}`)}}else if(W!=null)H.push(`已 ${h2(W*1000)}`);Z.push(` · ${Y} \`${J.name}\` · ${H.join(" · ")}`)}}return Z.join(`
99
+ `)}function bG($){let Z=$.peers??[];if(Z.length===0)return"_无_";return Z.map((J)=>{let Y=TG[J.status]??"·",Q=NG[J.status]??J.status,W=J.uptimeMs!=null&&J.uptimeMs>0?` · ${h2(J.uptimeMs)}`:"",H=J.isCurrent?" · 当前":"";return` · ${Y} \`${J.name}\` · ${Q}${W}${H}`}).join(`
100
+ `)}function B9($,Z=M.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:bG($)}]}}function CG($){let Z=$.model?`${$.model}${$.effort?`/${$.effort}`:""}`:$.effort?`强度 ${$.effort}`:"未就绪";return[`**\uD83E\uDD16 当前模型${$.provider==="claude"?` (${k8($.provider)})`:""}** \`${Z}\``,...$.worktreeInstructionNotice?[$.worktreeInstructionNotice]:[]].join(`
101
+ `)}function q9($,Z=M.consoleCurrentModel){return{tag:"markdown",element_id:Z,content:CG($)}}function L9($,Z=M.consoleHost){let J=yG($);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:xG($)}]}}function wG($){if($===void 0)return"**\uD83D\uDCCA 额度** _加载中…_";switch($.state){case"no_credentials":return"**\uD83D\uDCCA 额度** 未配置凭据 — 检查 config.toml [token_source.*]";case"not_applicable":return"**\uD83D\uDCCA 额度** —(该来源无额度查询)";case"rate_limited":return"**\uD83D\uDCCA 额度** API 限流,稍后重试";case"network":return`**\uD83D\uDCCA 额度** 拉取失败${$.reason?" — `"+$.reason+"`":""}`}let J=[$.planLabel?`**\uD83D\uDCCA 额度** · ${$.planLabel}`:"**\uD83D\uDCCA 额度**"];for(let Y of $.windows){let Q=[h1(Y.percent)];if(typeof Y.used==="number"&&typeof Y.total==="number")Q.push(`${Y.used}/${Y.total}`);if(Y.resetsAt)Q.push(`重置 ${V$(Y.resetsAt)}`);J.push(` · ${Y.label} ${Q.join(" · ")}`)}return J.length===1&&!$.planLabel?"**\uD83D\uDCCA 额度** _无数据_":J.join(`
102
+ `)}function I2($){let Z=$.unifiedUsage!==void 0?wG($.unifiedUsage):$.provider==="claude"?kG($.glmUsage):nJ($.usage);return{tag:"markdown",element_id:M.consoleUsage,content:Z}}function aJ($,Z){return[q9($,Z),B9($),L9($.sysinfo),I2($)]}function U8($){let{sessionName:Z,status:J}=$,Y=J==="working"?"blue":J==="awaiting_permission"?"orange":J==="stopped"?"grey":"green";return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83C\uDF1F Lodestar · ${Z}`},template:Y},body:{elements:aJ($)}}}function O8($){return g1($.sessionName,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择账号"}},expanded:!0,elements:[{tag:"markdown",content:`当前: ${t$($.currentDisplay??"未选择")}
103
+ 选账号进入模型选择。`},...$.providers.map((Z)=>fG(Z,$.panelId))]})}function fG($,Z){if(!$.enabled)return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${s0($.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=[$.selected?"当前账号":"",`${$.modelCount} 个模型`].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${s0($.display)}**
104
+ ${J}`}]},{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 E8($){return g1($.sessionName,oJ($))}function T8($){return g1($.sessionName,D9($))}function P9($){return g1($.sessionName,rJ($),"green")}function g1($,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 oJ($){let Z=hG($.models,$.panelId);return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择模型"}},expanded:!0,elements:[{tag:"markdown",content:[`当前: ${tJ($.currentModel,$.currentEffort)}`,"选模型进入 effort 选择。"].join(`
105
+ `)},...$.models.length?Z:[{tag:"markdown",content:"_未返回可用模型列表_"}],{tag:"button",text:{tag:"plain_text",content:"➕ 补录模型"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_custom_prompt",panel_id:$.panelId,...$.models[0]?.sourceId?{source_id:$.models[0].sourceId}:{}}}]}]}}function j9($,Z="cancelled"){return g1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:Z==="stale"?"_此补录面板已失效 — 当前等待中的补录未受影响_":"_已取消补录 — 列表未改动_"}]},"grey")}function N8($,Z,J){return g1($,{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:[`**直接回复模型名补录到 ${Z}**(列表外的模型,端点会先校验真伪)`,"_裸词命令(hi/stop/model 等)不受影响_"].join(`
106
+ `)},{tag:"button",text:{tag:"plain_text",content:"取消"},type:"default",width:"default",behaviors:[{type:"callback",value:{kind:"model_panel_cancel",panel_id:J}}]}]},"blue")}function R9($,Z,J){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"补录模型"}},expanded:!0,elements:[{tag:"markdown",content:$?`✅ \`${Z}\` 已加入列表`:`❌ \`${Z}\` 未加入 — ${J}`}]}}function D9($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择 effort"}},expanded:!0,elements:[{tag:"markdown",content:[`模型: ${cG($.model)}`,`当前: ${tJ($.currentModel,$.currentEffort)}`].join(`
107
+ `)},...$.model.efforts.length?$.model.efforts.map((Z)=>gG($.model,Z,$.panelId,$.currentModel,$.currentEffort)):[{tag:"markdown",content:"_该模型未返回可用 effort_"}]]}}function rJ($){return{tag:"collapsible_panel",element_id:M.modelPanel,header:{title:{tag:"plain_text",content:"选择已保存"}},expanded:!0,elements:[{tag:"markdown",content:["**已保存**",t$(sJ($.model,$.effort,$.provider)),s0($.scope)].join(`
108
+ `)}]}}function vG($,Z){if($.enabled===!1)return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`⚙️ **${s0($.displayName)}** · 未配置
109
+ ${s0($.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 J=$.displayName&&$.displayName!==$.model?`**${s0($.displayName)}**`:`**${t$($.model)}**`,Y=[$.isDefault?`${k8($.provider)} 默认`:"",$.selected?"当前模型":""].filter(Boolean),Q=$.description?`
110
+ `+s0(mG($.description,110)):"";return[{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[J,t$($.model),Y.length?Y.join(" · "):""].filter(Boolean).join(`
111
+ `)+Q}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:$.selected?"primary":"default",behaviors:[{type:"callback",value:IG($,Z)}]}]}]}]}function hG($,Z){let J=[{title:"Codex",models:$.filter((W)=>(W.provider??"codex")==="codex")},{title:"Claude Code 后端",models:$.filter((W)=>W.provider==="claude")}].filter((W)=>W.models.length>0),Y=(W)=>W.flatMap((H)=>vG(H,Z));if(J.length<=1)return Y($);let Q=[];for(let W of J)Q.push({tag:"markdown",content:`**${W.title}**`}),Q.push(...Y(W.models));return Q}function gG($,Z,J,Y,Q){let W=Y===$.model&&Q===Z.effort,H=[Z.isDefault?"默认":"",W?"当前":""].filter(Boolean).join(" · ");return{tag:"column_set",columns:[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:[`**${s0(Z.effort)}**`,H,Z.description?s0(Z.description):""].filter(Boolean).join(`
112
+ `)}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"选"},type:W?"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 IG($,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 cG($){return $.displayName&&$.displayName!==$.model?`${s0($.displayName)} (${t$($.model)})`:t$($.model)}function tJ($,Z){return t$(sJ($,Z))}function sJ($,Z,J){let Y=J&&J!=="codex"?`${k8(J)} · `:"";if($&&Z)return`${Y}${$}/${Z}`;if($)return`${Y}${$}`;if(Z)return`${Y}${Z}`;return"未选择"}function k8($){return $==="claude"?"Claude":"Codex"}function mG($,Z){return $.length<=Z?$:$.slice(0,Z-1)+"…"}function s0($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function t$($){return"`"+$.replace(/`/g,"\\`")+"`"}function z$($){let Z=[];if(Z.push($.suffix??"✅"),$.durationSec)Z.push(`⏱ ${$.durationSec}s`);if($.outputTokens!=null&&$.outputTokens>0)Z.push(`\uD83D\uDCF6 ${EG($.outputTokens)}`);return{config:{streaming_mode:!1,summary:{content:Z.join(" · ")}}}}var TG,NG,SG;var eJ=N(()=>{M8();y0();TG={idle:"\uD83D\uDFE2",working:"⚙️",awaiting_permission:"\uD83D\uDD10",starting:"\uD83D\uDE80",stopped:"⚪"},NG={idle:"闲",working:"工作中",awaiting_permission:"等审批",starting:"启动中",stopped:"未运行"};SG={active:"\uD83D\uDFE2",activating:"\uD83D\uDE80",reloading:"\uD83D\uDD04",inactive:"⚪",deactivating:"\uD83D\uDFE1",failed:"❌"}});function S8($){let Z=lG($);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83C\uDF3F wt"},template:uG($.notice)},body:{elements:[...$.notice?[pG($.notice)]:[],...Z?[{tag:"markdown",content:Z}]:[],...$.entries.flatMap(iG)]}}}function uG($){if($?.type==="error")return"red";if($?.type==="success")return"green";return"turquoise"}function pG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
113
113
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
114
- `)}}function kG($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${A6("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function SG($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Y=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${A6($.slug)}**
114
+ `)}}function lG($){let Z=$.hiddenMergedUnmountedCount??0;if(!$.entries.length&&Z===0)return`_无 work/* 分支。发 ${M9("wt name")} 创建。_`;if(Z>0)return`${Z}个已归档分支`;return""}function iG($){let Z=$.error?"出错":$.mounted&&$.dirtyCount&&$.dirtyCount>0?`有未提交改动 ${$.dirtyCount}`:$.state==="merged"?"已合并":$.state==="stale"?"两边都有新改动":$.mounted?"进行中":"未挂载",J=$.duplicateChatCount>1?`群重复 ${$.duplicateChatCount} 个`:$.chatId?"群正常":"无群",Y=[{tag:"column",width:"weighted",weight:4,elements:[{tag:"markdown",content:`**${M9($.slug)}**
115
115
  ${Z} · ${J}
116
- ${A6($.branch)}`}]}];if($.mounted||$.chatId)Y.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Y}]}function f2($){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(`
117
- `)}]}}}function A6($){return"`"+$.replace(/`/g,"\\`")+"`"}function L7($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
116
+ ${M9($.branch)}`}]}];if($.mounted||$.chatId)Y.push({tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"删"},type:"danger",behaviors:[{type:"callback",value:{kind:"worktree_disband",slug:$.slug}}]}]});return[{tag:"column_set",columns:Y}]}function c2($){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,M9($.branch),...$.body?[$.body]:[]].join(`
117
+ `)}]}}}function M9($){return"`"+$.replace(/`/g,"\\`")+"`"}function x8($){let Z=$.mode==="fork",J=Z?"分叉":"回退",Y=Z?"temp_fork_select":"temp_back_select",Q=Z?`\uD83D\uDCA1 选择一条「用户输入」,将在临时群从它**之前**创建独立对话分支;选中的输入本身不包含。
118
118
  分支与本群共享 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件,原会话不动。`:`⚠️ 选择一条「用户输入」,将停止本群当前 turn 和后台任务,并从它**之前**创建后续对话分支;选中的输入本身不包含。
119
- 只回退对话历史,不会回滚 cwd 中的文件。`,W=[];if($.notice)W.push({tag:"markdown",content:yG($.notice)});if(!$.entries.length)W.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{W.push({tag:"markdown",content:Q});for(let H of $.entries)W.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${M7(H.ts)}**
120
- ${U0(H.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Y,panel_id:$.panelId,choice_id:H.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`${Z?"\uD83D\uDD31 fk 分叉":"⏪ bk 回退"} · ${$.projectName}`},template:Z?"turquoise":"orange"},body:{elements:W}}}function P7($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
121
- 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${M7(J.ts)}**
122
- ${U0(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 D7($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
119
+ 只回退对话历史,不会回滚 cwd 中的文件。`,W=[];if($.notice)W.push({tag:"markdown",content:dG($.notice)});if(!$.entries.length)W.push({tag:"markdown",content:"_当前会话还没有已完成的 turn,无法分叉/回退。_"});else{W.push({tag:"markdown",content:Q});for(let H of $.entries)W.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${f8(H.ts)}**
120
+ ${E$(H.preview.slice(0,60)||"(空)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:J},type:Z?"primary":"danger",behaviors:[{type:"callback",value:{kind:Y,panel_id:$.panelId,choice_id:H.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`${Z?"\uD83D\uDD31 fk 分叉":"⏪ bk 回退"} · ${$.projectName}`},template:Z?"turquoise":"orange"},body:{elements:W}}}function b8($){let Z=[];if(!$.entries.length)Z.push({tag:"markdown",content:`_项目「${$.projectName}」没有可创建分支的历史会话。_`});else{Z.push({tag:"markdown",content:`\uD83D\uDCA1 选择一个历史会话,在**当前群**创建独立对话分支;源会话不动。
121
+ 新分支共享当前 cwd 和磁盘文件;只分叉对话历史,不复制或回滚文件。`});for(let J of $.entries)Z.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:5,elements:[{tag:"markdown",content:`**${f8(J.ts)}**
122
+ ${E$(J.preview.slice(0,60)||"(无摘要)")}`}]},{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"分支"},type:"primary",behaviors:[{type:"callback",value:{kind:"temp_resume_select",panel_id:$.panelId,choice_id:J.choiceId}}]}]}]})}return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs 独立分支 · ${$.projectName}`},template:"purple"},body:{elements:Z}}}function C8($){let Z=$.entries.length===0?"(回退范围内未观察到 Write/Edit/FileChange 类文件变更)":$.entries.map((J)=>{let Y=J.body.length>800?J.body.slice(0,800)+`
123
123
  …(截断)`:J.body;return`${J.path} (${J.tool})
124
124
  ${Y}`}).join(`
125
125
 
126
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function O0($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${R7($.message)}`}]}}}function j7($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Y=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Q=$.selectedPreview.slice(0,80)||"(无摘要)",W=$.sourceStatus?` · 状态 ${U0($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${U0(K6($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
126
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 观察到的文件变更 · ${$.projectName}`},template:"grey"},body:{elements:[{tag:"markdown",content:"以下是回退范围内观察到的文件变更,可复制、编辑后交给新分支参考。bk 只回退对话历史,不会回滚磁盘文件;Shell/MCP 等工具造成的副作用可能未被记录。"},{tag:"markdown",content:"```\n"+Z+"\n```"}]}}}function T$($){return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:$.title},template:$.ok?"green":"red"},body:{elements:[{tag:"markdown",content:`${$.ok?"✅":"❌"} ${y8($.message)}`}]}}}function w8($){let Z=$.provider==="codex"?"Codex":"Claude",J=$.bindingState==="changed"?"已接入":$.bindingState==="prepared"?"已准备":$.bindingState==="unchanged"?"未切换":"状态待确认",Y=$.bindingState==="changed"?"✅":$.bindingState==="prepared"?"⏳":$.bindingState==="unchanged"?"❌":"⚠️",Q=$.selectedPreview.slice(0,80)||"(无摘要)",W=$.sourceStatus?` · 状态 ${E$($.sourceStatus)}`:"",H=$.bindingState==="changed"?["**当前群**",`新会话 ${E$(F9($.newSessionId))}`,"","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
127
127
  `):$.bindingState==="prepared"?["**当前群**","Claude 独立分支已准备;发送下一条消息时生成并接入新会话。","","源会话未修改;新分支与当前群共享 cwd 和磁盘文件。"].join(`
128
- `):$.bindingState==="unchanged"?[`${R7($.message)}`,"",`本群原绑定 ${U0(K6($.previousSessionId))};源会话未修改。`].join(`
129
- `):[`${R7($.message)}`,"",`后端返回会话 ${U0(K6($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
130
- `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Y} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${M7($.selectedTs)}**${W}`,U0(Q),`源会话 ${U0(K6($.sourceSessionId))}`].join(`
131
- `)},{tag:"markdown",content:H}]}}}function M7($){let Z=new Date($),J=(Y)=>String(Y).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function U0($){return"`"+gJ($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function K6($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function R7($){return gJ($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function gJ($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function yG($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
128
+ `):$.bindingState==="unchanged"?[`${y8($.message)}`,"",`本群原绑定 ${E$(F9($.previousSessionId))};源会话未修改。`].join(`
129
+ `):[`${y8($.message)}`,"",`后端返回会话 ${E$(F9($.newSessionId))};当前绑定无法确认。`,"请发送 hi 或 rs 检查当前状态,不要把本卡视为成功回执。"].join(`
130
+ `);return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:`\uD83D\uDD01 rs ${J} · ${$.projectName}`},template:$.bindingState==="changed"?"green":$.bindingState==="prepared"?"purple":$.bindingState==="unchanged"?"red":"orange"},body:{elements:[{tag:"markdown",content:`${Y} ${$.bindingState==="changed"?"已从所选历史创建独立分支":$.bindingState==="prepared"?"已准备从所选历史创建独立分支":$.bindingState==="unchanged"?"历史分支创建失败":"分支结果需要确认"}`},{tag:"markdown",content:[`**所选历史 · ${Z}**`,`**${f8($.selectedTs)}**${W}`,E$(Q),`源会话 ${E$(F9($.sourceSessionId))}`].join(`
131
+ `)},{tag:"markdown",content:H}]}}}function f8($){let Z=new Date($),J=(Y)=>String(Y).padStart(2,"0");return`${J(Z.getMonth()+1)}-${J(Z.getDate())} ${J(Z.getHours())}:${J(Z.getMinutes())}`}function E$($){return"`"+$Y($.replace(/`/g,"\\`").replace(/\n/g," "))+"`"}function F9($){let Z=$?.trim()??"";if(!Z)return"MISS";return Z.length>13?`${Z.slice(0,8)}…${Z.slice(-4)}`:Z}function y8($){return $Y($).replace(/\\/g,"\\\\").replace(/([`*_{}\[\]()#+\-.!|>~])/g,"\\$1")}function $Y($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function dG($){let Z=$.type==="error"?"red":"grey";return $.content.split(`
132
132
  `).map((J)=>`<font color='${Z}'>${J||" "}</font>`).join(`
133
- `)}function IJ($){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(`
133
+ `)}function ZY($){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(`
134
134
  ---
135
- `);return""}function F7($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Y)=>Y&&typeof Y==="object").map((Y)=>({tool:$,path:typeof Y.path==="string"&&Y.path?Y.path:"?",body:typeof Y.diff==="string"?Y.diff:typeof Y.unified_diff==="string"?Y.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:IJ(Z)}]}function O7($){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?[bG($.notice)]:[],{tag:"markdown",element_id:M.tasklistPanel,content:xG($)},CG($)]}}}function xG($){let Z=[`项目:${U7($.projectName)}`,`清单:${U7($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
136
- `);if(Z.push("","已启用"),Z.push(`GUID:${U7($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
137
- `)}function CG($){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 bG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
138
- `).map((J)=>`<font color='${Z}'>${fG(J)||" "}</font>`).join(`
139
- `)}}function U7($){return"`"+$.replace(/`/g,"\\`")+"`"}function fG($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var cJ=S(()=>{S$()});import{createHash as wG}from"node:crypto";function N7($){let Z=[{tag:"markdown",element_id:M.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
140
- `)}];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)=>`- **${E0(J.display)}**:${E0(J.reason)}`).join(`
141
- `)}]});return Z.push(...$.catalog.map(gG),IG($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function k7($){let Z=q6($.workers.length);return{schema:"2.0",config:{update_multi:!0,streaming_mode:!pJ($.status),summary:{content:v2($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.parentKind==="follow_up"?"继续委派任务":"委派任务"} · ${$.workers.length} 位 Agent`},template:"purple"},body:{elements:[w2($),{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`任务说明 · ${T7($.prompt,56)}`}},expanded:!1,elements:[{tag:"markdown",content:mG($.prompt)}]},...$.workers.map((J)=>_6(J,Z,$.workers.length===1))]}}}function _6($,Z=uJ,J=!1){let Y=cG($),Q=[`模型 ${o0($.model)} · 推理 ${o0($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${iJ($.durationMs)}`);if($.status==="queued"&&$.queuedReason)Q.push("",E0($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let W of $.pendingInput.questions)if(Q.push(`- ${E0(W.question)}`),W.options.length)Q.push(` 选项:${W.options.map((H)=>o0(H.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",s($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",uG(s($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let W of $.steps.slice(-3)){let H=W.tool==="tool error"?"❌":W.phase==="completed"?"✓":W.phase==="started"?"→":"·",X=W.tool==="tool error"?"工具执行失败":W.tool==="tool result"?"工具执行完成":W.tool;Q.push(`- ${H} ${o0(X)} ${E0(T7(W.detail,180))}`)}}return{tag:"collapsible_panel",element_id:B6($.identityId),header:{title:{tag:"plain_text",content:`${Y} · ${T7($.identityName,48)}`}},expanded:$.status==="failed"||$.status==="needs_input"||J&&$.status==="completed"&&!!$.output,elements:[{tag:"markdown",content:Q.join(`
142
- `)}]}}function w2($){let Z=$.workers.filter((A)=>A.status==="completed").length,J=$.workers.filter((A)=>A.status==="failed").length,Y=$.workers.filter((A)=>A.status==="needs_input").length,Q=$.workers.filter((A)=>A.status==="running").length,W=$.workers.filter((A)=>A.status==="queued").length,H=$.workers.filter((A)=>A.status==="cancelled").length,X=[Q?`执行中 ${Q}`:"",W?`排队 ${W}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),V=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null,z=[`**${lJ($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...V!=null&&Number.isFinite(V)?[`⏱ 用时 ${iJ(V)}`]:[],...$.error?[E0($.error)]:[]];return{tag:"markdown",element_id:M.agentRunFooter,content:z.join(`
143
- `)}}function B6($){return`aw_${wG("sha256").update($).digest("hex").slice(0,16)}`}function q6($){let Z=Math.max(1,Math.floor($));return Math.min(uJ,Math.max(hG,Math.floor(vG/Z)))}function v2($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${lJ($)} · ${Z}/${$.workers.length}`}function gG($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${E0($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${o0($.id)}
144
- ${o0($.model)} · 默认 ${o0($.defaultEffort)} · ${E0(J)}`].join(`
145
- `)}}function IG($){return{tag:"column_set",columns:[E7("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),E7("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),E7("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function E7($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function cG($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function pJ($){return $==="completed"||$==="failed"||$==="cancelled"}function lJ($){switch($.status){case"completed":return"✅ 委派完成";case"failed":return"❌ 委派失败";case"cancelled":return"\uD83D\uDED1 委派已取消";case"needs_input":return"❓ 等待主 Agent 回复";case"queued":return"⏳ 等待执行";case"running":return $.workers.length>0&&$.workers.every((Z)=>pJ(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function iJ($){if(!Number.isFinite($)||$<0)return"—";let Z=Math.floor($/1000);if(Z<60)return`${Z} 秒`;let J=Math.floor(Z/60);if(J<60)return`${J} 分 ${Z%60} 秒`;return`${Math.floor(J/60)} 小时 ${J%60} 分`}function mG($){let Z=s($);if(Z.length<=mJ)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,mJ-J.length-2)}
146
-
147
- ${J}`}function uG($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
148
-
149
- ${J}`}function o0($){return"`"+$.replace(/`/g,"\\`")+"`"}function E0($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function T7($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var mJ=1e4,vG=48000,uJ=8000,hG=512;var dJ=S(()=>{S$()});function t0($){return pG.has($)?$:null}function R6($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function w1($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function r0($){return String($?.subject??$?.content??"").trim()}function S7($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function oJ($){return`subj:${$}`}function nJ($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function nG($){let Z=r0($);if(!Z)return null;return{id:w1($)||oJ(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:S7($)??"pending"}}function y7($,Z,J,Y){if(Z==="TaskList"){let Q=R6(Y),W=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(W===null)return $;let H=[];for(let X of W){let V=nG(X);if(V)H.push(V)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let z=R6(Y),A=Array.isArray(z?.tasks)?z.tasks:Array.isArray(z)?z:null,K=$;return Q.forEach((B,q)=>{let L=r0(B);if(!L)return;let R=A?.[q],D=R&&w1(R)||nJ(Y??"");K=aJ(K,D,L,B)}),K}let W=R6(Y),H=W?.task??W,X=w1(H)||nJ(Y??""),V=r0(H)||r0(J);if(!V)return $;return aJ($,X,V,J)}if(Z==="TaskUpdate"){let Q=w1(J);if(!Q)return $;let W=S7(J);if(W==="deleted")return $.filter((X)=>X.id!==Q);let H=r0(J);if($.some((X)=>X.id===Q))return $.map((X)=>X.id===Q?{...X,...W?{status:W}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:X);return $}if(Z==="TaskGet"){let Q=R6(Y),W=Q?.task??Q,H=w1(W)||w1(J);if(!H)return $;let X=$.find((A)=>A.id===H),V=r0(W)||X?.subject||r0(J);if(!V)return $;let z={id:H,subject:V,description:typeof W?.description==="string"?W.description:X?.description,activeForm:typeof W?.activeForm==="string"?W.activeForm:X?.activeForm,status:S7(W)??X?.status??"pending"};return X?$.map((A)=>A.id===H?z:A):[...$,z]}return $}function aJ($,Z,J,Y){let Q=Z||oJ(J),W={...typeof Y?.activeForm==="string"&&Y.activeForm?{activeForm:Y.activeForm}:{},...typeof Y?.description==="string"&&Y.description?{description:Y.description}:{}};if($.some((H)=>H.id===Q))return $.map((H)=>H.id===Q?{...H,id:Q,subject:J,...W}:H);return[...$,{id:Q,subject:J,status:"pending",...W}]}function x7($){let Z=$.filter((W)=>W.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let W of Z){let H=iG[W.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((W)=>J.has(W)?`${W} ${J.get(W)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function rJ($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let X=parseInt(H,10);return Number.isNaN(X)?Number.MAX_SAFE_INTEGER:X},W=[...J].sort((H,X)=>{let V=Q(H.id)-Q(X.id);return V!==0?V:H.id.localeCompare(X.id)});for(let H of W.slice(0,12)){let X=dG[H.status],V=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${X} ${V||"(空)"}`)}if(W.length>12)Y.push(`- 还有 ${W.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
150
- `)}function T0($,Z,J,Y){let Q=lG[J.name],W=x7(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${W}`;return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:rJ(Z,Y)}]}}function s0($){return{tag:"collapsible_panel",element_id:M.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${x7($)}`}},expanded:!0,elements:[{tag:"markdown",content:rJ($)}]}}var pG,lG,iG,dG;var tJ=S(()=>{S$();pG=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);lG={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},iG={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},dG={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var f$=S(()=>{S$();t3();FJ();hJ();cJ();dJ();tJ();d9()});import{spawn as aG}from"node:child_process";class D6{proc;buf="";nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor(){this.proc=aG(Z2(),["app-server","--listen","stdio://"],{stdio:["pipe","pipe","pipe"],shell:process.platform==="win32"}),this.exitPromise=new Promise((Z)=>{this.resolveExit=Z}),this.proc.stdout.on("data",(Z)=>this.onStdout(Z)),this.proc.stderr.on("data",(Z)=>{let J=Z.toString().trim();if(J)G(`usage[codex stderr]: ${J}`)});let $=(Z)=>{if(!this.alive)return;this.alive=!1;for(let[J,Y]of this.pending)clearTimeout(Y.timer),Y.reject(Error(`${Z.message}; pending ${Y.method} id=${J}`));this.pending.clear(),this.resolveExit()};this.proc.on("error",(Z)=>$(Error(`codex app-server spawn failed: ${Z.message}`))),this.proc.on("exit",(Z,J)=>{$(Error(`codex app-server exited code=${Z} signal=${J}`))})}onStdout($){this.buf+=$.toString();let Z;while((Z=this.buf.indexOf(`
151
- `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch{continue}if(!Object.prototype.hasOwnProperty.call(Y,"id"))continue;let Q=this.pending.get(Y.id);if(!Q)continue;if(this.pending.delete(Y.id),clearTimeout(Q.timer),Y.error)Q.reject(Error(JSON.stringify(Y.error)));else Q.resolve(Y.result)}}request($,Z,J=h2){let Y=this.nextId++;return new Promise((Q,W)=>{if(!this.alive){W(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;W(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:W,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
152
- `,(X)=>{if(!X)return;let V=this.pending.get(Y);if(!V)return;this.pending.delete(Y),clearTimeout(V.timer),V.reject(Error(`codex app-server write failed for ${$}: ${X.message}`))})}catch(X){this.pending.delete(Y),clearTimeout(H),W(X instanceof Error?X:Error(String(X)))}})}async close($=2000){if(!this.alive)return;if(!this.proc.kill("SIGTERM"))throw Error("codex app-server rejected SIGTERM");if(await Promise.race([this.exitPromise.then(()=>!0),new Promise((Y)=>setTimeout(()=>Y(!1),$))]))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await Promise.race([this.exitPromise.then(()=>!0),new Promise((Y)=>setTimeout(()=>Y(!1),$))]))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}}function L6($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function oG($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function P6($){if(!$)return null;return{percent:oG($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function rG($){let Z=P6($?.primary),J=P6($?.secondary),Y=(W)=>W?.durationMins!=null&&W.durationMins>0&&W.durationMins<=720,Q=(W)=>W?.durationMins!=null&&W.durationMins>720;if(Y(Z)&&Q(J))return{fiveHour:Z,weekly:J};if(Y(J)&&Q(Z))return{fiveHour:J,weekly:Z};if(Q(Z)&&!J)return{fiveHour:null,weekly:Z};if(Q(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function tG($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,W]of J){let{fiveHour:H,weekly:X}=rG(W);if(!H&&!X)continue;Y.push({limitId:Q,limitName:W?.limitName??null,fiveHour:H,weekly:X})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function sG($){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 eJ($){let Z=sG($),J=e0?.state==="ok"?e0.buckets??[]:[],Y=J.filter((Q)=>sJ(Q.fiveHour,P6($?.primary))&&sJ(Q.weekly,P6($?.secondary)));if(J.length>0&&Y.length===0)G(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${Z})`);else if($?.limitId&&Y.length===1&&Y[0].limitId!==$.limitId)G(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${Y[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function sJ($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function eG(){let $=new D6;try{await L6($.request("initialize",{clientInfo:{name:"lodestar-usage",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}),h2);let J=(await L6($.request("account/read",{}),h2))?.account;if(!J)return{state:"no_credentials"};if(J.type!=="chatgpt")return{state:"auth_failed"};let Y=await L6($.request("account/rateLimits/read",{}),h2);return $Y(Y,J.planType)}catch(Z){return G(`usage: codex app-server usage failed: ${Z?.message??Z}`),{state:"network",reason:Z?.message??String(Z)}}finally{await $.close()}}function $Y($,Z){let{buckets:J,defaultLimitId:Y}=tG($),Q=J.find((W)=>W.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};return{state:"ok",subscriptionType:Z??Q.limitName??$?.rateLimits?.planType??"chatgpt",fiveHour:Q.fiveHour,weekly:Q.weekly,buckets:J,defaultLimitId:Q.limitId,fetchedAt:Date.now()}}function ZY(){return e0}async function j6(){if(v1)return v1;return v1=eG().then(($)=>{if(v1=null,$.state==="network")return e0??$;return e0=$,$}).catch(($)=>{return G(`usage: fetchUsage threw: ${$}`),v1=null,e0??{state:"network",reason:String($)}}),v1}function JY($){return C7??=L6($("account/rateLimits/read",{}),h2).then((Z)=>{let J=$Y(Z);if(J.state==="ok")e0=J;else G(`usage: refresh from connection: ${J.state==="network"?J.reason:J.state}`);return J}).catch((Z)=>{return G(`usage: refresh from connection failed: ${Z?.message??Z}`),null}).finally(()=>{C7=null}),C7}var h2=1e4,e0=null,v1=null,C7=null;var M6=S(()=>{P1();g()});import{readFileSync as $A}from"node:fs";import{homedir as ZA}from"node:os";import{join as HY}from"node:path";function JA(){return process.env.CLAUDE_CONFIG_DIR||HY(ZA(),".claude")}function f7(){try{let $=$A(HY(JA(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return G(`glm-usage: read settings.json env failed: ${$}`),{}}}function F6($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function YA($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function QA($){let Z=YA($);return Z&&F6($)?Z:null}function QY($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function WY($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function WA($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((A)=>A?.type==="TOKENS_LIMIT"),Y=J.find((A)=>A?.unit===3&&A?.number===5),Q=J.find((A)=>A?.unit===6&&A?.number===1),W=Z.find((A)=>A?.type==="TIME_LIMIT"),H=(A)=>A?{percent:QY(A.percentage),resetsAt:WY(A.nextResetTime)}:null,X=H(Y),V=H(Q),z=W?{percent:QY(W.percentage),resetsAt:WY(W.nextResetTime),...typeof W.currentValue==="number"?{used:W.currentValue}:{},...typeof W.usage==="number"?{total:W.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:X,weekly:V,monthly:z,fetchedAt:Date.now()}}async function w7($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:f7(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let W=QA(Q);if(!W)return{state:"not_glm",baseUrl:Q||void 0};let H=`${W}/api/monitor/usage/quota/limit`,X=new AbortController,V=setTimeout(()=>X.abort(),YY);try{let z=await fetch(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:X.signal});if(z.status===429)return{state:"rate_limited"};if(!z.ok)return{state:"network",reason:`HTTP ${z.status}`};let A=await z.json();if(A?.success===!1||typeof A?.code==="number"&&A.code!==200)return{state:"network",reason:A?.msg?String(A.msg):`code ${A?.code}`};let K=A?.data??A;return WA(K)}catch(z){let A=z?.name==="AbortError"?`timeout ${YY}ms`:z?.message??String(z);return G(`glm-usage: quota/limit fetch failed: ${A}`),{state:"network",reason:A}}finally{clearTimeout(V)}}async function v7(){if(h1)return h1;return h1=w7().then(($)=>{if(h1=null,$.state==="network")return b7??$;return b7=$,$}).catch(($)=>{return G(`glm-usage: fetchGlmUsage threw: ${$}`),h1=null,b7??{state:"network",reason:String($)}}),h1}var YY=1e4,b7=null,h1=null;var U6=S(()=>{g()});function XY($){let Z=[];for(let J of $.matchAll(HA)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function O6($,Z=process.platform){if(Z!=="win32")return $;let J=XA.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var HA,XA;var h7=S(()=>{HA=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;XA=/^\/([a-zA-Z])\//});function GY($){if(VY.test($))return{marker:"start",body:$.replace(VY,"")};if(zY.test($))return{marker:"end",body:$.replace(zY,"")};return{marker:"none",body:$}}var VY,zY;var AY=S(()=>{VY=/^>{3,}[ \t]?/,zY=/^<{3,}[ \t]?/});async function KY($,Z,J,Y,Q){let{marker:W,body:H}=GY(Z);if(W==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)I7($,"reopen");return $.multiMsgBuffer=[],g7($,H,J,Y,Q),!0}if(W==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return G(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}g7($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:V}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await zA($,X,V),!0}if($.multiMsgBuffer!==null)return g7($,Z,J,Y,Q),!0;return!1}function g7($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)VA($,Q)}function VA($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await T$(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else P$(Z,J)})()}async function zA($,Z,J){for(let[H,X]of J)if(X)P$(H,X);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){G(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await N($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((H)=>{return(H.files.length?H.files.map((V)=>`[file: ${V}]`).join(" ")+`
135
+ `);return""}function v8($,Z){if(!Z||typeof Z!=="object")return[];if($==="FileChange"||$==="fileChange"){if(!Array.isArray(Z.changes))return[];return Z.changes.filter((Y)=>Y&&typeof Y==="object").map((Y)=>({tool:$,path:typeof Y.path==="string"&&Y.path?Y.path:"?",body:typeof Y.diff==="string"?Y.diff:typeof Y.unified_diff==="string"?Y.unified_diff:""}))}if(!["Write","Edit","NotebookEdit","MultiEdit"].includes($))return[];let J=Z.file_path??Z.path??Z.notebook_path;return[{tool:$,path:typeof J==="string"&&J?J:"?",body:ZY(Z)}]}function g8($){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?[oG($.notice)]:[],{tag:"markdown",element_id:M.tasklistPanel,content:nG($)},aG($)]}}}function nG($){let Z=[`项目:${h8($.projectName)}`,`清单:${h8($.tasklistName)}`];if(!$.binding)return Z.push("","未启用"),Z.join(`
136
+ `);if(Z.push("","已启用"),Z.push(`GUID:${h8($.binding.guid)}`),$.binding.url)Z.push(`链接:${$.binding.url}`);if($.confirmDelete)Z.push(""),Z.push("<font color='red'>确认后会删除该清单以及清单内所有任务。</font>");return Z.join(`
137
+ `)}function aG($){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 oG($){let Z=$.type==="error"?"red":$.type==="success"?"green":"grey";return{tag:"markdown",content:$.content.split(`
138
+ `).map((J)=>`<font color='${Z}'>${rG(J)||" "}</font>`).join(`
139
+ `)}}function h8($){return"`"+$.replace(/`/g,"\\`")+"`"}function rG($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var JY=N(()=>{y0()});import{createHash as tG}from"node:crypto";function m8($){let Z=[{tag:"markdown",element_id:M.agentIdentityPanel,content:["**全局 Agent 身份**","选择一个或多个 Agent 执行任务,由主 Agent 统一分配和汇总结果。",`目录第 ${$.page+1}/${$.totalPages} 页`].join(`
140
+ `)}];if($.failures.length)Z.push({tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`MISS · ${$.failures.length} 个账号`}},expanded:!1,elements:[{tag:"markdown",content:$.failures.map((J)=>`- **${N$(J.display)}**:${N$(J.reason)}`).join(`
141
+ `)}]});return Z.push(...$.catalog.map($A),ZA($)),{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:"\uD83E\uDDE0 可用 Agent"},template:"purple"},body:{elements:Z}}}function u8($){let Z=E9($.workers.length);return{schema:"2.0",config:{update_multi:!0,streaming_mode:!WY($.status),summary:{content:u2($)}},header:{title:{tag:"plain_text",content:`\uD83E\uDDE0 ${$.parentKind==="follow_up"?"继续委派任务":"委派任务"} · ${$.workers.length} 位 Agent`},template:"purple"},body:{elements:[m2($),{tag:"collapsible_panel",header:{title:{tag:"plain_text",content:`任务说明 · ${c8($.prompt,56)}`}},expanded:!1,elements:[{tag:"markdown",content:YA($.prompt)}]},...$.workers.map((J)=>U9(J,Z,$.workers.length===1))]}}}function U9($,Z=QY,J=!1){let Y=JA($),Q=[`模型 ${s$($.model)} · 推理 ${s$($.effort)}`];if($.durationMs!=null)Q.push(`用时 ${XY($.durationMs)}`);if($.status==="queued"&&$.queuedReason)Q.push("",N$($.queuedReason));if($.pendingInput){Q.push("","**等待主 Agent 回答**");for(let W of $.pendingInput.questions)if(Q.push(`- ${N$(W.question)}`),W.options.length)Q.push(` 选项:${W.options.map((H)=>s$(H.label)).join(" / ")}`)}if($.error)Q.push("",$.status==="cancelled"?"**停止原因**":"**失败原因**",d($.error));if($.output)Q.push("",$.status==="failed"||$.status==="cancelled"?"**已生成的内容**":"**结果**",QA(d($.output),Z));if(!$.output&&!$.error&&!$.pendingInput)Q.push("",$.status==="completed"?"_任务已完成,没有正文输出。_":$.status==="cancelled"?"_任务已取消。_":$.status==="queued"?"_等待开始执行。_":"_正在执行任务,结果会显示在这里。_");if($.steps.length){Q.push("","**最近动作**");for(let W of $.steps.slice(-3)){let H=W.tool==="tool error"?"❌":W.phase==="completed"?"✓":W.phase==="started"?"→":"·",X=W.tool==="tool error"?"工具执行失败":W.tool==="tool result"?"工具执行完成":W.tool;Q.push(`- ${H} ${s$(X)} ${N$(c8(W.detail,180))}`)}}return{tag:"collapsible_panel",element_id:O9($.identityId),header:{title:{tag:"plain_text",content:`${Y} · ${c8($.identityName,48)}`}},expanded:$.status==="failed"||$.status==="needs_input"||J&&$.status==="completed"&&!!$.output,elements:[{tag:"markdown",content:Q.join(`
142
+ `)}]}}function m2($){let Z=$.workers.filter((G)=>G.status==="completed").length,J=$.workers.filter((G)=>G.status==="failed").length,Y=$.workers.filter((G)=>G.status==="needs_input").length,Q=$.workers.filter((G)=>G.status==="running").length,W=$.workers.filter((G)=>G.status==="queued").length,H=$.workers.filter((G)=>G.status==="cancelled").length,X=[Q?`执行中 ${Q}`:"",W?`排队 ${W}`:"",Y?`待答 ${Y}`:"",J?`失败 ${J}`:"",H?`已取消 ${H}`:""].filter(Boolean),V=$.finishedAt?Date.parse($.finishedAt)-Date.parse($.createdAt):null,z=[`**${HY($)}** · 完成 ${Z}/${$.workers.length}`,...X.length?[X.join(" · ")]:[],...V!=null&&Number.isFinite(V)?[`⏱ 用时 ${XY(V)}`]:[],...$.error?[N$($.error)]:[]];return{tag:"markdown",element_id:M.agentRunFooter,content:z.join(`
143
+ `)}}function O9($){return`aw_${tG("sha256").update($).digest("hex").slice(0,16)}`}function E9($){let Z=Math.max(1,Math.floor($));return Math.min(QY,Math.max(eG,Math.floor(sG/Z)))}function u2($){let Z=$.workers.filter((J)=>J.status==="completed").length;return`${HY($)} · ${Z}/${$.workers.length}`}function $A($){let J=$.status==="ready"?"可用":`不可用:${$.reason??"MISS"}`;return{tag:"markdown",content:[`**${N$($.displayName)}** ${$.sourceDefault?"· 默认":""}`,`${s$($.id)}
144
+ ${s$($.model)} · 默认 ${s$($.defaultEffort)} · ${N$(J)}`].join(`
145
+ `)}}function ZA($){return{tag:"column_set",columns:[I8("上一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.max(0,$.page-1)}),I8("刷新",{kind:"agent_identity_page",panel_id:$.panelId,page:$.page}),I8("下一页",{kind:"agent_identity_page",panel_id:$.panelId,page:Math.min($.totalPages-1,$.page+1)})]}}function I8($,Z){return{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:$},type:"default",behaviors:[{type:"callback",value:Z}]}]}}function JA($){switch($.status){case"completed":return"✅ 完成";case"failed":return"❌ 失败";case"cancelled":return"\uD83D\uDED1 取消";case"needs_input":return"❓ 等待输入";case"running":return"⏳ 运行中";default:return"⏳ 排队中"}}function WY($){return $==="completed"||$==="failed"||$==="cancelled"}function HY($){switch($.status){case"completed":return"✅ 委派完成";case"failed":return"❌ 委派失败";case"cancelled":return"\uD83D\uDED1 委派已取消";case"needs_input":return"❓ 等待主 Agent 回复";case"queued":return"⏳ 等待执行";case"running":return $.workers.length>0&&$.workers.every((Z)=>WY(Z.status))?"⏳ 正在收尾":"⏳ 正在执行"}}function XY($){if(!Number.isFinite($)||$<0)return"—";let Z=Math.floor($/1000);if(Z<60)return`${Z} 秒`;let J=Math.floor(Z/60);if(J<60)return`${J} 分 ${Z%60} 秒`;return`${Math.floor(J/60)} 小时 ${J%60} 分`}function YA($){let Z=d($);if(Z.length<=YY)return Z;let J="_这里仅显示任务预览,Agent 使用的是完整任务内容。_";return`${Z.slice(0,YY-J.length-2)}
146
+
147
+ ${J}`}function QA($,Z){if($.length<=Z)return $;let J="_这里仅显示结果预览,完整内容已保存。_";return`${$.slice(0,Math.max(0,Z-J.length-2))}
148
+
149
+ ${J}`}function s$($){return"`"+$.replace(/`/g,"\\`")+"`"}function N$($){return $.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function c8($,Z){let J=$.replace(/\s+/g," ").trim();return J.length<=Z?J:`${J.slice(0,Z-1)}…`}var YY=1e4,sG=48000,QY=8000,eG=512;var VY=N(()=>{y0()});function $1($){return WA.has($)?$:null}function T9($){if(!$)return null;try{let Z=JSON.parse($);return Z&&typeof Z==="object"?Z:null}catch{return null}}function I1($){return String($?.taskId??$?.id??$?.task_id??"").trim()}function e$($){return String($?.subject??$?.content??"").trim()}function p8($){let Z=$?.status;return Z==="pending"||Z==="in_progress"||Z==="completed"||Z==="deleted"?Z:void 0}function AY($){return`subj:${$}`}function zY($){let Z=$.match(/#\s*(\d+)/);return Z?Z[1]:""}function zA($){let Z=e$($);if(!Z)return null;return{id:I1($)||AY(Z),subject:Z,description:typeof $?.description==="string"?$.description:void 0,activeForm:typeof $?.activeForm==="string"?$.activeForm:void 0,status:p8($)??"pending"}}function l8($,Z,J,Y){if(Z==="TaskList"){let Q=T9(Y),W=Array.isArray(Q?.tasks)?Q.tasks:Array.isArray(Q)?Q:null;if(W===null)return $;let H=[];for(let X of W){let V=zA(X);if(V)H.push(V)}return H}if(Z==="TaskCreate"){let Q=Array.isArray(J?.tasks)?J.tasks:null;if(Q){let z=T9(Y),G=Array.isArray(z?.tasks)?z.tasks:Array.isArray(z)?z:null,_=$;return Q.forEach((B,q)=>{let L=e$(B);if(!L)return;let P=G?.[q],R=P&&I1(P)||zY(Y??"");_=GY(_,R,L,B)}),_}let W=T9(Y),H=W?.task??W,X=I1(H)||zY(Y??""),V=e$(H)||e$(J);if(!V)return $;return GY($,X,V,J)}if(Z==="TaskUpdate"){let Q=I1(J);if(!Q)return $;let W=p8(J);if(W==="deleted")return $.filter((X)=>X.id!==Q);let H=e$(J);if($.some((X)=>X.id===Q))return $.map((X)=>X.id===Q?{...X,...W?{status:W}:{},...H?{subject:H}:{},...typeof J?.activeForm==="string"?{activeForm:J.activeForm}:{}}:X);return $}if(Z==="TaskGet"){let Q=T9(Y),W=Q?.task??Q,H=I1(W)||I1(J);if(!H)return $;let X=$.find((G)=>G.id===H),V=e$(W)||X?.subject||e$(J);if(!V)return $;let z={id:H,subject:V,description:typeof W?.description==="string"?W.description:X?.description,activeForm:typeof W?.activeForm==="string"?W.activeForm:X?.activeForm,status:p8(W)??X?.status??"pending"};return X?$.map((G)=>G.id===H?z:G):[...$,z]}return $}function GY($,Z,J,Y){let Q=Z||AY(J),W={...typeof Y?.activeForm==="string"&&Y.activeForm?{activeForm:Y.activeForm}:{},...typeof Y?.description==="string"&&Y.description?{description:Y.description}:{}};if($.some((H)=>H.id===Q))return $.map((H)=>H.id===Q?{...H,id:Q,subject:J,...W}:H);return[...$,{id:Q,subject:J,status:"pending",...W}]}function i8($){let Z=$.filter((W)=>W.status!=="deleted");if(Z.length===0)return"空";let J=new Map;for(let W of Z){let H=XA[W.status];J.set(H,(J.get(H)??0)+1)}let Q=["进行中","待办","完成"].map((W)=>J.has(W)?`${W} ${J.get(W)}`:"").filter(Boolean).join(" · ");return`${Z.length} 项${Q?` · ${Q}`:""}`}function _Y($,Z){let J=$.filter((H)=>H.status!=="deleted"),Y=[`**待办**: ${J.length} 项`],Q=(H)=>{let X=parseInt(H,10);return Number.isNaN(X)?Number.MAX_SAFE_INTEGER:X},W=[...J].sort((H,X)=>{let V=Q(H.id)-Q(X.id);return V!==0?V:H.id.localeCompare(X.id)});for(let H of W.slice(0,12)){let X=VA[H.status],V=H.status==="in_progress"&&H.activeForm?H.activeForm:H.subject;Y.push(`- ${X} ${V||"(空)"}`)}if(W.length>12)Y.push(`- 还有 ${W.length-12} 项未显示`);if(Z)Y.push(""),Y.push(Z);return Y.join(`
150
+ `)}function k$($,Z,J,Y){let Q=HA[J.name],W=i8(Z),H=`${J.status} \uD83D\uDD27 ${Q}: ${W}`;return{tag:"collapsible_panel",element_id:M.tool($),header:{title:{tag:"plain_text",content:H}},expanded:!1,elements:[{tag:"markdown",content:_Y(Z,Y)}]}}function Z1($){return{tag:"collapsible_panel",element_id:M.taskBoardLive,header:{title:{tag:"plain_text",content:`\uD83D\uDCCB 任务总览 · ${i8($)}`}},expanded:!0,elements:[{tag:"markdown",content:_Y($)}]}}var WA,HA,XA,VA;var KY=N(()=>{y0();WA=new Set(["TaskCreate","TaskUpdate","TaskList","TaskGet"]);HA={TaskCreate:"创建任务",TaskUpdate:"更新任务",TaskList:"任务列表",TaskGet:"查看任务"},XA={pending:"待办",in_progress:"进行中",completed:"完成",deleted:"已删"},VA={pending:"⬜",in_progress:"\uD83D\uDD04",completed:"✅",deleted:"\uD83D\uDDD1️"}});var f0=N(()=>{y0();KJ();gJ();eJ();JY();VY();KY();H7()});import{spawn as GA}from"node:child_process";class S9{proc;buf="";nextId=1;alive=!0;exitPromise;resolveExit;pending=new Map;constructor(){this.proc=GA(z2(),["app-server","--listen","stdio://"],{stdio:["pipe","pipe","pipe"],shell:process.platform==="win32"}),this.exitPromise=new Promise((Z)=>{this.resolveExit=Z}),this.proc.stdout.on("data",(Z)=>this.onStdout(Z)),this.proc.stderr.on("data",(Z)=>{let J=Z.toString().trim();if(J)A(`usage[codex stderr]: ${J}`)});let $=(Z)=>{if(!this.alive)return;this.alive=!1;for(let[J,Y]of this.pending)clearTimeout(Y.timer),Y.reject(Error(`${Z.message}; pending ${Y.method} id=${J}`));this.pending.clear(),this.resolveExit()};this.proc.on("error",(Z)=>$(Error(`codex app-server spawn failed: ${Z.message}`))),this.proc.on("exit",(Z,J)=>{$(Error(`codex app-server exited code=${Z} signal=${J}`))})}onStdout($){this.buf+=$.toString();let Z;while((Z=this.buf.indexOf(`
151
+ `))>=0){let J=this.buf.slice(0,Z).trim();if(this.buf=this.buf.slice(Z+1),!J)continue;let Y;try{Y=JSON.parse(J)}catch{continue}if(!Object.prototype.hasOwnProperty.call(Y,"id"))continue;let Q=this.pending.get(Y.id);if(!Q)continue;if(this.pending.delete(Y.id),clearTimeout(Q.timer),Y.error)Q.reject(Error(JSON.stringify(Y.error)));else Q.resolve(Y.result)}}request($,Z,J=p2){let Y=this.nextId++;return new Promise((Q,W)=>{if(!this.alive){W(Error(`codex app-server is not alive; cannot request ${$}`));return}let H=setTimeout(()=>{if(!this.pending.delete(Y))return;W(Error(`codex app-server ${$} timed out after ${J}ms`))},J);this.pending.set(Y,{resolve:Q,reject:W,method:$,timer:H});try{this.proc.stdin.write(JSON.stringify({id:Y,method:$,params:Z})+`
152
+ `,(X)=>{if(!X)return;let V=this.pending.get(Y);if(!V)return;this.pending.delete(Y),clearTimeout(V.timer),V.reject(Error(`codex app-server write failed for ${$}: ${X.message}`))})}catch(X){this.pending.delete(Y),clearTimeout(H),W(X instanceof Error?X:Error(String(X)))}})}async close($=2000){if(!this.alive)return;if(!this.proc.kill("SIGTERM"))throw Error("codex app-server rejected SIGTERM");if(await Promise.race([this.exitPromise.then(()=>!0),new Promise((Y)=>setTimeout(()=>Y(!1),$))]))return;if(!this.proc.kill("SIGKILL"))throw Error("codex app-server rejected SIGKILL");if(!await Promise.race([this.exitPromise.then(()=>!0),new Promise((Y)=>setTimeout(()=>Y(!1),$))]))throw Error(`codex app-server did not exit after SIGKILL (${$}ms)`)}}function N9($,Z){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function AA($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function k9($){if(!$)return null;return{percent:AA($.usedPercent),resetsAt:typeof $.resetsAt==="number"?new Date($.resetsAt*1000):null,durationMins:typeof $.windowDurationMins==="number"?$.windowDurationMins:null}}function _A($){let Z=k9($?.primary),J=k9($?.secondary),Y=(W)=>W?.durationMins!=null&&W.durationMins>0&&W.durationMins<=720,Q=(W)=>W?.durationMins!=null&&W.durationMins>720;if(Y(Z)&&Q(J))return{fiveHour:Z,weekly:J};if(Y(J)&&Q(Z))return{fiveHour:J,weekly:Z};if(Q(Z)&&!J)return{fiveHour:null,weekly:Z};if(Q(J)&&!Z)return{fiveHour:null,weekly:J};return{fiveHour:Z,weekly:J}}function KA($){let Z=$?.rateLimitsByLimitId,J=Z&&typeof Z==="object"?Object.entries(Z):$?.rateLimits?[[$.rateLimits.limitId??"codex",$.rateLimits]]:[],Y=[];for(let[Q,W]of J){let{fiveHour:H,weekly:X}=_A(W);if(!H&&!X)continue;Y.push({limitId:Q,limitName:W?.limitName??null,fiveHour:H,weekly:X})}return{buckets:Y,defaultLimitId:$?.rateLimits?.limitId??void 0}}function BA($){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 qY($){let Z=BA($),J=J1?.state==="ok"?J1.buckets??[]:[],Y=J.filter((Q)=>BY(Q.fiveHour,k9($?.primary))&&BY(Q.weekly,k9($?.secondary)));if(J.length>0&&Y.length===0)A(`usage: rate-limit notification matches NO known bucket — possible relabel or new bucket, will resolve on next read. (${Z})`);else if($?.limitId&&Y.length===1&&Y[0].limitId!==$.limitId)A(`usage: rate-limit notification labeled limitId=${$.limitId} but content matches bucket ${Y[0].limitId} (known codex parser fallback relabels; ignoring notification payload)`)}function BY($,Z){if(!$||!Z)return!$&&!Z;return $.percent===Z.percent&&$.durationMins===Z.durationMins&&$.resetsAt?.getTime()===Z.resetsAt?.getTime()}async function qA(){let $=new S9;try{await N9($.request("initialize",{clientInfo:{name:"lodestar-usage",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}),p2);let J=(await N9($.request("account/read",{}),p2))?.account;if(!J)return{state:"no_credentials"};if(J.type!=="chatgpt")return{state:"auth_failed"};let Y=await N9($.request("account/rateLimits/read",{}),p2);return LY(Y,J.planType)}catch(Z){return A(`usage: codex app-server usage failed: ${Z?.message??Z}`),{state:"network",reason:Z?.message??String(Z)}}finally{await $.close()}}function LY($,Z){let{buckets:J,defaultLimitId:Y}=KA($),Q=J.find((W)=>W.limitId===Y)??J[0];if(!Q)return{state:"network",reason:"empty rate limit response"};return{state:"ok",subscriptionType:Z??Q.limitName??$?.rateLimits?.planType??"chatgpt",fiveHour:Q.fiveHour,weekly:Q.weekly,buckets:J,defaultLimitId:Q.limitId,fetchedAt:Date.now()}}function PY(){return J1}async function y9(){if(c1)return c1;return c1=qA().then(($)=>{if(c1=null,$.state==="network")return J1??$;return J1=$,$}).catch(($)=>{return A(`usage: fetchUsage threw: ${$}`),c1=null,J1??{state:"network",reason:String($)}}),c1}function jY($){return d8??=N9($("account/rateLimits/read",{}),p2).then((Z)=>{let J=LY(Z);if(J.state==="ok")J1=J;else A(`usage: refresh from connection: ${J.state==="network"?J.reason:J.state}`);return J}).catch((Z)=>{return A(`usage: refresh from connection failed: ${Z?.message??Z}`),null}).finally(()=>{d8=null}),d8}var p2=1e4,J1=null,c1=null,d8=null;var x9=N(()=>{F1();I()});import{readFileSync as LA}from"node:fs";import{homedir as PA}from"node:os";import{join as FY}from"node:path";function jA(){return process.env.CLAUDE_CONFIG_DIR||FY(PA(),".claude")}function a8(){try{let $=LA(FY(jA(),"settings.json"),"utf8"),Z=JSON.parse($)?.env;return Z&&typeof Z==="object"?Z:{}}catch($){return A(`glm-usage: read settings.json env failed: ${$}`),{}}}function b9($){try{let Z=new URL($).hostname.toLowerCase();return Z==="open.bigmodel.cn"||Z==="dev.bigmodel.cn"||Z==="api.z.ai"}catch{return!1}}function RA($){try{let Z=new URL($);return`${Z.protocol}//${Z.host}`}catch{return null}}function DA($){let Z=RA($);return Z&&b9($)?Z:null}function DY($){return typeof $==="number"&&isFinite($)?Math.max(0,Math.min(100,$)):null}function MY($){return typeof $==="number"&&isFinite($)&&$>0?new Date($):null}function MA($){let Z=Array.isArray($?.limits)?$.limits:[],J=Z.filter((G)=>G?.type==="TOKENS_LIMIT"),Y=J.find((G)=>G?.unit===3&&G?.number===5),Q=J.find((G)=>G?.unit===6&&G?.number===1),W=Z.find((G)=>G?.type==="TIME_LIMIT"),H=(G)=>G?{percent:DY(G.percentage),resetsAt:MY(G.nextResetTime)}:null,X=H(Y),V=H(Q),z=W?{percent:DY(W.percentage),resetsAt:MY(W.nextResetTime),...typeof W.currentValue==="number"?{used:W.currentValue}:{},...typeof W.usage==="number"?{total:W.usage}:{}}:null;return{state:"ok",level:typeof $?.level==="string"&&$.level?$.level:void 0,fiveHour:X,weekly:V,monthly:z,fetchedAt:Date.now()}}async function o8($,Z){let J=$&&Z?{ANTHROPIC_BASE_URL:$,ANTHROPIC_AUTH_TOKEN:Z}:a8(),Y=J.ANTHROPIC_AUTH_TOKEN,Q=J.ANTHROPIC_BASE_URL||"";if(!Y)return{state:"no_credentials"};let W=DA(Q);if(!W)return{state:"not_glm",baseUrl:Q||void 0};let H=`${W}/api/monitor/usage/quota/limit`,X=new AbortController,V=setTimeout(()=>X.abort(),RY);try{let z=await fetch(H,{headers:{Authorization:Y,"Content-Type":"application/json","Accept-Language":"en-US,en"},signal:X.signal});if(z.status===429)return{state:"rate_limited"};if(!z.ok)return{state:"network",reason:`HTTP ${z.status}`};let G=await z.json();if(G?.success===!1||typeof G?.code==="number"&&G.code!==200)return{state:"network",reason:G?.msg?String(G.msg):`code ${G?.code}`};let _=G?.data??G;return MA(_)}catch(z){let G=z?.name==="AbortError"?`timeout ${RY}ms`:z?.message??String(z);return A(`glm-usage: quota/limit fetch failed: ${G}`),{state:"network",reason:G}}finally{clearTimeout(V)}}async function r8(){if(m1)return m1;return m1=o8().then(($)=>{if(m1=null,$.state==="network")return n8??$;return n8=$,$}).catch(($)=>{return A(`glm-usage: fetchGlmUsage threw: ${$}`),m1=null,n8??{state:"network",reason:String($)}}),m1}var RY=1e4,n8=null,m1=null;var C9=N(()=>{I()});function UY($){let Z=[];for(let J of $.matchAll(FA)){let Y=J[1]?.trim();if(Y)Z.push(Y)}return Z}function w9($,Z=process.platform){if(Z!=="win32")return $;let J=UA.exec($);if(!J)return $;return`${J[1].toUpperCase()}:\\`+$.slice(J[0].length).replace(/\//g,"\\")}var FA,UA;var t8=N(()=>{FA=/\[\[send:[ \t]*([^\n]*?)[ \t]*\]\]/g;UA=/^\/([a-zA-Z])\//});function TY($){if(OY.test($))return{marker:"start",body:$.replace(OY,"")};if(EY.test($))return{marker:"end",body:$.replace(EY,"")};return{marker:"none",body:$}}var OY,EY;var NY=N(()=>{OY=/^>{3,}[ \t]?/,EY=/^<{3,}[ \t]?/});async function kY($,Z,J,Y,Q){let{marker:W,body:H}=TY(Z);if(W==="start"){if($.multiMsgBuffer!==null&&$.multiMsgBuffer.length>0)e8($,"reopen");return $.multiMsgBuffer=[],s8($,H,J,Y,Q),!0}if(W==="end"){if($.multiMsgBuffer===null){if(H.trim()||J.length)return!1;return A(`session "${$.sessionName}": end marker without active multi-msg buffer, ignoring`),!0}s8($,H,J,Y,Q);let{multiMsgBuffer:X,multiMsgReactions:V}=$;return $.multiMsgBuffer=null,$.multiMsgReactions=new Map,await EA($,X,V),!0}if($.multiMsgBuffer!==null)return s8($,Z,J,Y,Q),!0;return!1}function s8($,Z,J,Y,Q){if(Z.trim()||J.length)$.multiMsgBuffer.push({text:Z,files:J,userOpenId:Y,msgId:Q});if(Q)OA($,Q)}function OA($,Z){$.multiMsgReactions.set(Z,""),(async()=>{let J=await T0(Z,"Pin");if(!J)return;if($.multiMsgReactions.has(Z))$.multiMsgReactions.set(Z,J);else j0(Z,J)})()}async function EA($,Z,J){for(let[H,X]of J)if(X)j0(H,X);let Y=Z.filter((H)=>H.text.trim()||H.files.length);if(Y.length===0){A(`session "${$.sessionName}": multi-msg flush with empty buffer, not sent`),await T($.chatId,"⚠️ 多条消息缓冲为空,未发送(只收到标记没有正文)。");return}let Q=Y.map((H)=>{return(H.files.length?H.files.map((V)=>`[file: ${V}]`).join(" ")+`
153
153
  `:"")+H.text}).join(`
154
154
 
155
- `),W=Y[Y.length-1];G(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],W.userOpenId,W.msgId)}function I7($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;G(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)P$(Y,Q);T$(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var _Y=S(()=>{o();g();AY()});import{mkdtemp as AA,rm as KA,writeFile as _A}from"node:fs/promises";import{createRequire as BA}from"node:module";import{tmpdir as qA}from"node:os";import{join as BY}from"node:path";function UA($){let Z=PY.get($);if(Z)return Z;let{liteAdaptor:J}=Z1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=Z1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=Z1("mathjax-full/js/mathjax.js"),{TeX:W}=Z1("mathjax-full/js/input/tex.js"),{AllPackages:H}=Z1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=Z1("mathjax-full/js/output/svg.js"),V=J({fontSize:$});Y(V);let z=Q.document("",{InputJax:new W({packages:H}),OutputJax:new X({fontCache:"none"})}),A={adaptor:V,doc:z};return PY.set($,A),A}function DY($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function OA($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function EA($,Z=u7,J=!0){try{let Y=Z*RA,{adaptor:Q,doc:W}=UA(Z),H=W.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),X=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(X)){let F$=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(F$)}let V=X.indexOf("<svg"),z=X.lastIndexOf("</svg>");if(V<0||z<0)throw Error("MathJax returned no SVG");let A=X.slice(V,z+6),K=A.match(/^<svg\b[^>]*>/)?.[0];if(!K)throw Error("MathJax returned malformed SVG root");let B=DY(K.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),q=DY(K.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),L=K.match(/\bviewBox="([^"]+)"/)?.[1];if(!L)throw Error("MathJax SVG missing viewBox");let R=L.trim().split(/[\s,]+/).map(Number);if(R.length!==4||R.some((F$)=>!Number.isFinite(F$))||R[2]<=0||R[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[D,U,P,j]=R,O=/<text\b/.test(A)?MA:0,b=`${D} ${U} ${P+O} ${j}`,x=B*Y,m=O*(x/P),h=Math.max(1,Math.ceil(x+m)),I=Math.max(1,Math.ceil(q*Y)),T=LA-c7*2,k=Math.min(1,T/h),u=Math.max(1,Math.round(h*k)),E=Math.max(1,Math.round(I*k));if(k<1&&E<PA)throw Error(`formula would be unreadable after width cap (${u}x${E})`);let y=u+c7*2,f=E+RY*2,M$=A.slice(K.length,-6).replace(/currentColor/g,qY).replace(/font-family="serif"/g,`font-family="${FA}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${y}" height="${f}" viewBox="0 0 ${y} ${f}" style="color:${qY}">`,`<rect x="0" y="0" width="${y}" height="${f}" rx="6" fill="${UY}"/>`,`<svg x="${c7}" y="${RY}" width="${u}" height="${E}" viewBox="${OA(b)}" preserveAspectRatio="xMidYMid meet">`,M$,"</svg>","</svg>"].join(""),width:y,height:f}}catch(Y){return G(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function TA($,Z=u7,J=!0){let Y=EA($,Z,J);if(!Y)return null;try{let{Resvg:Q}=Z1("@resvg/resvg-js"),H=new Q(Y.svg,{background:UY,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:LY,sansSerifFamily:LY}}).render().asPng(),X=new DataView(H.buffer,H.byteOffset,H.byteLength),V=X.getUint32(16),z=X.getUint32(20);if(V!==Y.width||z!==Y.height)throw Error(`PNG dimensions ${V}x${z} != SVG ${Y.width}x${Y.height}`);return{png:H,width:V,height:z}}catch(Q){return G(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function NA($){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 jY($,Z){let J=[],Y=(A,K,B)=>{let q=A[0],L=K.trim();if(!L)return;J.push({start:Z+A.index,end:Z+A.index+q.length,tex:L,raw:q,display:B})},Q,W=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=W.exec($))!==null)Y(Q,Q[1]??Q[2]??"",!0);let H=/\\\(([\s\S]+?)\\\)/g;while((Q=H.exec($))!==null)Y(Q,Q[1]??"",!1);let X=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=X.exec($))!==null){let A=(Q[1]??"").trim();if(NA(A))Y(Q,A,!1)}J.sort((A,K)=>A.start-K.start||K.end-A.end);let V=[],z=-1;for(let A of J){if(A.start<z)continue;V.push(A),z=A.end}return V}function OY($){let Z=y9($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...jY($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...jY($.slice(Y),Y));return J}function kA($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Y)=>{if(MY[Y])return MY[Y];if(Y==="times")return"×";if(Y==="cdot")return"·";if(Y==="div")return"÷";if(Y==="pm")return"±";if(Y==="leq"||Y==="le")return"≤";if(Y==="geq"||Y==="ge")return"≥";if(Y==="neq"||Y==="ne")return"≠";if(Y==="approx")return"≈";if(Y==="sim")return"~";if(Y==="infty")return"∞";if(Y==="partial")return"∂";if(Y==="nabla")return"∇";if(Y==="sqrt")return"√";if(Y==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Y,Q)=>Q.length===1?`${Y}${Q}`:`${Y}(${Q})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function CA($){let Z=FY.get($);if(Z!==void 0)return Z;return Z=yA++,FY.set($,Z),Z}function bA($,Z){return`${jA}\x00${CA(Z)}\x00${$}`}function fA($){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 wA($,Z){let J=bA($,Z),Y=$1.get(J);if(Y)return Y;let Q=m7.get(J);if(Q)return Q;let W=(async()=>{let H=TA($,u7,!0);if(!H)return null;let X=null;try{X=await AA(BY(qA(),"lodestar-math-"));let V=BY(X,`formula-${fA($)}.png`);await _A(V,H.png);let z=await Z(V,{tex:$,width:H.width,height:H.height});if(!z)return G(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let A={key:z,width:H.width,height:H.height};if($1.has(J))$1.delete(J);$1.set(J,A);while($1.size>xA){let K=$1.keys().next().value;if(typeof K!=="string")break;$1.delete(K)}return A}catch(V){return G(`math-render: upload failed for ${$.slice(0,80)}…: ${V}`),null}finally{if(X)try{await KA(X,{recursive:!0,force:!0})}catch(V){G(`math-render: temp cleanup failed for ${X}: ${V}`)}}})();m7.set(J,W);try{return await W}finally{m7.delete(J)}}function vA($,Z,J){let Y=$.width<=DA;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Y?"crop_center":"fit_horizontal",...Y?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function EY($,Z={}){let J=OY($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??SA,Q=await Promise.all(J.map(async(A)=>{if(!A.display){let K=kA(A.tex);if(K!==null)return{unicode:K,uploaded:null}}return{unicode:null,uploaded:await wA(A.tex,Y)}})),W=[],H="",X=0,V=0,z=()=>{if(!H)return;if(H.trim())W.push({type:"markdown",text:H});H=""};for(let A=0;A<J.length;A++){let K=J[A],B=Q[A];if(H+=$.slice(X,K.start),B.unicode!==null){H+=B.unicode,X=K.end;continue}let q=B.uploaded;if(!q){H+=K.raw,X=K.end;continue}z(),W.push(vA(q,K,V++)),X=K.end}if(H+=$.slice(X),z(),!W.length)W.push({type:"markdown",text:$});return{blocks:W,formulaCount:J.length,renderedImageCount:V}}function p7($){return OY($).length>0}var Z1,RA=0.5,u7=22,qY="#1F2329",UY="#F7F8FA",c7=12,RY=8,LA=720,PA=14,DA=278,jA="v4-native-cjk-tail-pad",MA=1100,LY,FA="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",PY,MY,SA=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (o(),$$));return Z($)},FY,yA=1,$1,m7,xA=512;var TY=S(()=>{g();Z1=BA(import.meta.url),LY=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",PY=new Map;MY={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:"Ω"};FY=new WeakMap,$1=new Map,m7=new Map});import{isAbsolute as gA}from"node:path";function _$($){if($?.planLiveInserted)return M.planLive;return $?.taskLiveInserted?M.taskBoardLive:M.footer}function IA($){return $==="ImageGeneration"||$==="imageGeneration"}function cA($,Z,J){if(J||!IA($))return null;let Y=O6(Z.trim());return gA(Y)?Y:null}function mA($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function NY($,Z,J){return $==="read"?S2(Z,J):k2(Z,J)}function kY($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=mA(J);if(Q&&$.currentTurn.openBatchI!==null){let V=$.currentTurn.openBatchI,z=$.currentTurn.toolBatches.get(V);if(z&&z.kind===Q){let A=z.items.length;z.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:V,name:J,input:Y,batchSlot:A});let K=Q==="read"?S2(V,z.items):k2(V,z.items);n($.currentTurn.cardId,M.tool(V),K),E6($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let W=t0(J);if(W){let V=$.currentTurn;if(W==="TaskCreate"&&!V.taskBoardResetThisTurn)$.taskBoard=[],V.taskBoardResetThisTurn=!0;if(!V.taskLiveInserted)V.taskLiveInserted=!0,X$(V.cardId,s0($.taskBoard),{type:"insert_before",targetElementId:M.footer});else n(V.cardId,M.taskBoardLive,s0($.taskBoard));let z=W==="TaskCreate";if(z)V.taskUpdateI=null;else V.taskCreateI=null;let A=(z?V.taskCreateI:V.taskUpdateI)===null;if(A)if(z)V.taskCreateI=V.toolCount++;else V.taskUpdateI=V.toolCount++;let K=z?V.taskCreateI:V.taskUpdateI;V.toolByUseId.set(Z,{i:K,name:J,input:Y});let B=T0(K,$.taskBoard,{name:W,status:"⏳"});A?X$(V.cardId,B,{type:"insert_before",targetElementId:_$(V)}):n(V.cardId,M.tool(K),B),E6(V,J,Y);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let H=$.currentTurn.toolCount++;if(Q){$.currentTurn.openBatchI=H;let V=[{toolUseId:Z,input:Y,output:null,isError:!1}];$.currentTurn.toolBatches.set(H,{kind:Q,items:V}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y,batchSlot:0});let z=Q==="read"?S2(H,V):k2(H,V);X$($.currentTurn.cardId,z,{type:"insert_before",targetElementId:_$($.currentTurn)}),E6($.currentTurn,J,Y);return}if($.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y}),J==="AskUserQuestion"){let V=Array.isArray(Y?.questions)?Y.questions:[],z=V.length>0?0:void 0,A=new Map;$.pendingAsks.set(Z,{questions:V,i:H,answers:{},answered:A,currentIdx:z});let K=O2(H,Z,V,"\uD83E\uDD14",{currentIdx:z,answered:A});if(X$($.currentTurn.cardId,K,{type:"insert_before",targetElementId:_$($.currentTurn)}),$.currentTurn.userOpenId&&$.currentTurn.messageId){let B=$.currentTurn,q=V[0]?.question?.trim()??"",L=q.length>40?q.slice(0,40)+"…":q,R=V.length>1?`❓ 待回答 ${V.length} 题${L?`: ${L}`:""}`:L?`❓ ${L}`:"❓ 等你回答问题";(async()=>{A$(B.cardId),await g4(B.cardId,{config:{summary:{content:R}}}),await l0(B.messageId,[B.userOpenId])})()}return}let X=F0(H,J,Y,null,"⏳");X$($.currentTurn.cardId,X,{type:"insert_before",targetElementId:_$($.currentTurn)}),E6($.currentTurn,J,Y)}function E6($,Z,J){if(!$)return;let Y=j0(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,W=n0(Z),H=Q?`\uD83D\uDD27 ${W}: ${Q}`:`\uD83D\uDD27 ${W}`;H0($.cardId,H)}function SY($,Z,J,Y){if(!$.currentTurn)return;let Q=$.currentTurn.toolByUseId.get(Z);if(!Q)return;let W=typeof J==="string"?J:Array.isArray(J)?J.map((z)=>z?.text??JSON.stringify(z)).join(`
156
- `):JSON.stringify(J);if(Q.output=W,Q.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=cA(Q.name,W,Y);if(H)$.sendOutboundPath(H,Q.name);if(Q.name==="AskUserQuestion"){T6($);return}if(Q.batchSlot!=null){let z=$.currentTurn.toolBatches.get(Q.i);if(z){let A=z.items[Q.batchSlot];if(A)A.output=W,A.isError=Y;let K=NY(z.kind,Q.i,z.items);n($.currentTurn.cardId,M.tool(Q.i),K)}T6($);return}let X=t0(Q.name);if(X){uA($,Q,X,Q.input,W,Y,Q.resolvedNote);return}let V=F0(Q.i,Q.name,Q.input,W,Y?"❌":"✅",Q.resolvedNote);n($.currentTurn.cardId,M.tool(Q.i),V),T6($)}function uA($,Z,J,Y,Q,W,H){if(!$.currentTurn)return;if(!W)$.taskBoard=y7($.taskBoard,J,Y,Q);let X=T0(Z.i,$.taskBoard,{name:J,status:W?"❌":"✅"},H);if(n($.currentTurn.cardId,M.tool(Z.i),X),$.currentTurn.taskLiveInserted)n($.currentTurn.cardId,M.taskBoardLive,s0($.taskBoard));T6($)}function T6($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function l7($,Z,J,Y,Q,W=$.currentTurn){let H=W;if(!H)return;for(let[X,V]of Y){if(H.toolByUseId.has(X))continue;let z=V.batchSlot??null,A=V.input,K,B;if(z!=null){let P=Q.get(V.i)?.items[z];if(!P)continue;A=P.input,K=P.output,B=P.isError}else K=V.output??null,B=V.isError??!1;let q=K!=null,L=y1(Z,M.tool(V.i));if(q&&!L)continue;if(z!=null){let P=Q.get(V.i)?.kind;if(!P)continue;let j=H.toolCount++,O={toolUseId:X,input:A,output:K,isError:B};H.toolBatches.set(j,{kind:P,items:[O]}),H.toolByUseId.set(X,{...V,i:j,batchSlot:0}),X$(J,NY(P,j,[O]),{type:"insert_before",targetElementId:_$(H)});continue}let R=t0(V.name);if(R){let P=R==="TaskCreate";if(P)H.taskUpdateI=null;else H.taskCreateI=null;let j=(P?H.taskCreateI:H.taskUpdateI)===null;if(j)if(P)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let O=P?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(X,{...V,i:O});let b=!q?"⏳":B?"❌":"✅",x=T0(O,$.taskBoard,{name:R,status:b},V.resolvedNote);j?X$(J,x,{type:"insert_before",targetElementId:_$(H)}):n(J,M.tool(O),x);continue}let D=H.toolCount++;H.toolByUseId.set(X,{...V,i:D});let U=!q?"⏳":B?"❌":"✅";X$(J,F0(D,V.name,V.input,K,U,V.resolvedNote),{type:"insert_before",targetElementId:_$(H)})}}var yY=S(()=>{h7();d0();f$();o()});function xY($){return $.pendingAsks.size>0}async function CY($,Z,J,Y){let Q=$.pendingAsks.entries().next();if(Q.done){G(`session "${$.sessionName}": onAskMessageAnswer with no pending — falling back to onUserMessage`),await $.onUserMessage(Z,[],J,Y);return}let[W,H]=Q.value;if(H.currentIdx===void 0){if(H.requestId){G(`session "${$.sessionName}": pending ask ${W} awaiting finalize — ignoring message`);return}G(`session "${$.sessionName}": pending ask ${W} orphaned (no can_use_tool) — dropping zombie, reprocessing as user message`),$.pendingAsks.delete(W),await $.onUserMessage(Z,[],J,Y);return}if(await i7($,W,H.currentIdx,Z,J)&&Y)T$(Y,"CheckMark")}async function bY($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return G(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==W.currentIdx)return G(`session "${$.sessionName}": stale ask click q=${J} current=${W.currentIdx}`),!1;return fY($,Z,{optionIdx:Y,user:Q})}async function i7($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return G(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return G(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==W.currentIdx)return G(`session "${$.sessionName}": stale ask custom q=${J} current=${W.currentIdx}`),!1;return fY($,Z,{customText:H,user:Q})}function fY($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=Y.currentIdx,W=Y.questions[Q];if(!W)return G(`session "${$.sessionName}": advanceAsk currentIdx=${Q} out of range`),!1;let H;if(J.customText!==void 0)H=J.customText;else if(J.optionIdx!==void 0){let K=W.options?.[J.optionIdx];if(!K)return G(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;H=K.label}else return G(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[W.question]=H,Y.answered.set(Q,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let X=Y.questions.length,V=void 0;for(let K=Q+1;K<X;K++)if(!Y.answered.has(K)){V=K;break}Y.currentIdx=V;let z=$.currentTurn,A=z?.toolByUseId.get(Z);if(z&&A){let K=O2(A.i,Z,Y.questions,V===void 0?"✅":"\uD83E\uDD14",{currentIdx:V,answered:Y.answered});n(z.cardId,M.tool(A.i),K)}if(V===void 0)if(Y.requestId)d7($,Z);else G(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`);return!0}function d7($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Y=$.currentTurn?.toolByUseId.get(Z),Q=Y?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Q,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Y)Y.output=JSON.stringify({answers:J.answers}),Y.isError=!1;if($.pendingAsks.delete(Z),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var n7=S(()=>{d0();f$();o();g()});async function wY($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return G(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let W=$.proc;if(!W)return G(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{W.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(z){return G(`session "${$.sessionName}": permission response ${Z} failed: ${z}`),{ok:!1,message:`权限决定发送失败: ${z instanceof Error?z.message:z}`}}$.pendingPermissions.delete(Z);let X=$.currentTurn,V=X?.toolByUseId.get(Q.toolUseId);if(X&&V){let z=t0(V.name);if(J==="deny"){let A=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,K=z?T0(V.i,$.taskBoard,{name:z,status:"❌"},A):F0(V.i,V.name,V.input,A,"❌");n(X.cardId,M.tool(V.i),K)}else{let A=J==="allow_always"?"始终允许":"已允许";V.resolvedNote=`✅ **${A}** by ${Y||"匿名"}`;let K=z?T0(V.i,$.taskBoard,{name:z,status:"⏳"},V.resolvedNote):F0(V.i,V.name,V.input,null,"⏳",V.resolvedNote);n(X.cardId,M.tool(V.i),K)}}if(G(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Q.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function vY($,Z){let J=$.currentTurn;if(!J){G(`session "${$.sessionName}": can_use_tool with no current turn — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no active turn"});return}let Y=Z.tool_use_id;if(!Y){G(`session "${$.sessionName}": can_use_tool without tool_use_id — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no tool_use_id"});return}let Q=J.toolByUseId.get(Y);if(!Q){G(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Y} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Q.name==="AskUserQuestion"){let H=$.pendingAsks.get(Y);if(!H){G(`session "${$.sessionName}": AskUserQuestion ${Y} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(H.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Y}),H.currentIdx===void 0)d7($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),G(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let W=W7(Q.i,Q.name,Q.input,Z.request_id);if(n(J.cardId,M.tool(Q.i),W),J.userOpenId&&J.messageId){let H=j0(Q.name,Q.input),X=n0(Q.name),V=H&&H.length>30?H.slice(0,30)+"…":H,z=V?`\uD83D\uDD10 等审批: ${X} · ${V}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{A$(J.cardId),await g4(J.cardId,{config:{summary:{content:z}}}),await l0(J.messageId,[J.userOpenId])})()}}var hY=S(()=>{d0();f$();o();g();n7()});function gY($,Z=cY){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function IY($){return typeof $==="string"&&dA.includes($)?$:null}async function mY(){let $=new D6;try{await gY($.request("initialize",{clientInfo:{name:"lodestar-models",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}));let Z=await gY($.request("model/list",{})),J=Array.isArray(Z?.data)?Z.data:[],Y=[];for(let Q of J){if(!Q||Q.hidden||!Q.id)continue;let W=(Array.isArray(Q.supportedReasoningEfforts)?Q.supportedReasoningEfforts:[]).map((X)=>IY(X?.reasoningEffort)).filter((X)=>X!==null);if(!W.length)continue;let H=IY(Q.defaultReasoningEffort)??W[0];Y.push({model:String(Q.id),display:typeof Q.displayName==="string"&&Q.displayName?String(Q.displayName):String(Q.id),efforts:W,defaultEffort:H})}return Y}finally{await $.close()}}async function uY($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,W=await fetch(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(cY)});if(!W.ok)throw Error(`HTTP ${W.status}`);let H=await W.json();return(Array.isArray(H?.data)?H.data:[]).filter((V)=>V&&(V.display_name||V.id)).map((V)=>{let z=String(V.display_name||V.id);return{model:z,display:z,efforts:i$,defaultEffort:"max"}})}var cY=1e4,dA,i$;var g2=S(()=>{M6();dA=["none","minimal","low","medium","high","xhigh","max","ultra"];i$=["max","xhigh","high","medium","low"]});import{existsSync as nA}from"node:fs";import{homedir as aA}from"node:os";import{join as pY}from"node:path";function N6($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function oA($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[]};let Z=[];if($.fiveHour)Z.push(N6($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(N6($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt}}function rA($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Y=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(N6(J.fiveHour,"fiveHour",`${Y} 5h`));if(J.weekly)Z.push(N6(J.weekly,"weekly",`${Y} 周`))}return Z.length?Z:null}function tA(){let $=process.env.CODEX_HOME||pY(aA(),".codex");return nA(pY($,"auth.json"))}var lY=S(()=>{U$();G$();M6();g2();g();J0({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=tA(),J=$.model?.trim()||void 0,Y=$.effort?.trim()||void 0,Q={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",enabled:Z,models:[],modelCatalogState:{status:Z?"idle":"disabled",updatedAt:Date.now()},defaultModel:J??"",async refreshModels(){if(!Q.enabled){Q.models=[],Q.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Q.modelCatalogState={status:"loading",updatedAt:null};try{if(Q.models=await mY(),Y)for(let W of Q.models)W.defaultEffort=Y;if(!J)Q.defaultModel=Q.models[0]?.model??"";Q.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){G(`codex-sub refreshModels MISS: ${W?.message??W}`),Q.models=[],Q.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let H=g0(W);return Object.assign(H,v.codex.env),H},resolveSpawnModel(W){return W},async readUsage(){let W=await j6(),H=oA(W),X=rA(W);if(X)H.windows=X;return H}};return Q}})});function eA($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function k6($,Z,J){try{let Y=await fetch(eA($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(sA)});if(Y.ok)return"exists";if(Y.status===400){let Q=await Y.text();return Q.includes("1214")||Q.includes("不存在")||Q.includes("not exist")?"not_found":"no_verdict"}return G(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return G(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var sA=15000;var a7=S(()=>{g()});function iY($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function $K($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function ZK($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function JK($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function YK($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function QK($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(iY($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(iY($.weekly,"weekly","周额度"));if($.monthly)Z.push($K($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var dY=S(()=>{G$();U6();g2();P4();a7();g();J0({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Y=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Q=!!(J&&Y)&&F6(J),W=$.model?.trim()||void 0,H=YK($.slots),X={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let V=await uY(J,Y),A=ZK($.models).filter((K)=>!V.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:i$,defaultEffort:"max"}));if(X.models=[...V,...A],!W)X.defaultModel=JK(X.models.map((K)=>K.model));for(let K of X.models){let B=L4("glm",K.model);K.context1m=B!=null&&B>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){G(`glm refreshModels MISS: ${V?.message??V}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V?.message??String(V)}}},spawnEnv(V){let A={...g0(V)};if(A.ANTHROPIC_BASE_URL=J,A.ANTHROPIC_AUTH_TOKEN=Y,H.opus)A.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)A.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)A.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return A},resolveSpawnModel(V){return R4("glm",V)},async verifyModel(V){return k6(J,{Authorization:`Bearer ${Y}`},V)},async readUsage(){return QK(await w7(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
155
+ `),W=Y[Y.length-1];A(`session "${$.sessionName}": multi-msg flush ${Y.length} segment(s) → 1 turn`),await $.onUserMessage(Q,[],W.userOpenId,W.msgId)}function e8($,Z){if($.multiMsgBuffer===null)return;let J=$.multiMsgBuffer.length;A(`session "${$.sessionName}": clear multi-msg buffer (${Z}): ${J} segment(s)`);for(let[Y,Q]of $.multiMsgReactions){if(Q)j0(Y,Q);T0(Y,"CrossMark")}$.multiMsgBuffer=null,$.multiMsgReactions=new Map}var SY=N(()=>{s();I();NY()});import{mkdtemp as NA,rm as kA,writeFile as SA}from"node:fs/promises";import{createRequire as yA}from"node:module";import{tmpdir as xA}from"node:os";import{join as yY}from"node:path";function IA($){let Z=wY.get($);if(Z)return Z;let{liteAdaptor:J}=Q1("mathjax-full/js/adaptors/liteAdaptor.js"),{RegisterHTMLHandler:Y}=Q1("mathjax-full/js/handlers/html.js"),{mathjax:Q}=Q1("mathjax-full/js/mathjax.js"),{TeX:W}=Q1("mathjax-full/js/input/tex.js"),{AllPackages:H}=Q1("mathjax-full/js/input/tex/AllPackages.js"),{SVG:X}=Q1("mathjax-full/js/output/svg.js"),V=J({fontSize:$});Y(V);let z=Q.document("",{InputJax:new W({packages:H}),OutputJax:new X({fontCache:"none"})}),G={adaptor:V,doc:z};return wY.set($,G),G}function fY($,Z){let J=Number.parseFloat($??"");if(!Number.isFinite(J)||J<=0)throw Error(`MathJax SVG missing valid ${Z}`);return J}function cA($){return $.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function mA($,Z=J5,J=!0){try{let Y=Z*bA,{adaptor:Q,doc:W}=IA(Z),H=W.convert($,{display:J,em:Z,ex:Y,containerWidth:80*Z}),X=Q.outerHTML(H);if(/data-mjx-error=|mjx-merror/.test(X)){let F0=X.match(/data-mjx-error="([^"]+)"/)?.[1]??"MathJax parse error";throw Error(F0)}let V=X.indexOf("<svg"),z=X.lastIndexOf("</svg>");if(V<0||z<0)throw Error("MathJax returned no SVG");let G=X.slice(V,z+6),_=G.match(/^<svg\b[^>]*>/)?.[0];if(!_)throw Error("MathJax returned malformed SVG root");let B=fY(_.match(/\bwidth="([\d.]+)ex"/)?.[1],"width"),q=fY(_.match(/\bheight="([\d.]+)ex"/)?.[1],"height"),L=_.match(/\bviewBox="([^"]+)"/)?.[1];if(!L)throw Error("MathJax SVG missing viewBox");let P=L.trim().split(/[\s,]+/).map(Number);if(P.length!==4||P.some((F0)=>!Number.isFinite(F0))||P[2]<=0||P[3]<=0)throw Error("MathJax SVG has invalid viewBox");let[R,O,j,D]=P,E=/<text\b/.test(G)?hA:0,x=`${R} ${O} ${j+E} ${D}`,b=B*Y,u=E*(b/j),g=Math.max(1,Math.ceil(b+u)),c=Math.max(1,Math.ceil(q*Y)),S=CA-$5*2,k=Math.min(1,S/g),h=Math.max(1,Math.round(g*k)),U=Math.max(1,Math.round(c*k));if(k<1&&U<wA)throw Error(`formula would be unreadable after width cap (${h}x${U})`);let y=h+$5*2,w=U+bY*2,M0=G.slice(_.length,-6).replace(/currentColor/g,xY).replace(/font-family="serif"/g,`font-family="${gA}"`);return{svg:[`<svg xmlns="http://www.w3.org/2000/svg" width="${y}" height="${w}" viewBox="0 0 ${y} ${w}" style="color:${xY}">`,`<rect x="0" y="0" width="${y}" height="${w}" rx="6" fill="${IY}"/>`,`<svg x="${$5}" y="${bY}" width="${h}" height="${U}" viewBox="${cA(x)}" preserveAspectRatio="xMidYMid meet">`,M0,"</svg>","</svg>"].join(""),width:y,height:w}}catch(Y){return A(`math-render: TeX→SVG failed for ${$.slice(0,80)}…: ${Y}`),null}}function uA($,Z=J5,J=!0){let Y=mA($,Z,J);if(!Y)return null;try{let{Resvg:Q}=Q1("@resvg/resvg-js"),H=new Q(Y.svg,{background:IY,fitTo:{mode:"original"},shapeRendering:2,textRendering:1,font:{loadSystemFonts:!0,serifFamily:CY,sansSerifFamily:CY}}).render().asPng(),X=new DataView(H.buffer,H.byteOffset,H.byteLength),V=X.getUint32(16),z=X.getUint32(20);if(V!==Y.width||z!==Y.height)throw Error(`PNG dimensions ${V}x${z} != SVG ${Y.width}x${Y.height}`);return{png:H,width:V,height:z}}catch(Q){return A(`math-render: SVG→PNG failed for ${$.slice(0,80)}…: ${Q}`),null}}function pA($){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 vY($,Z){let J=[],Y=(G,_,B)=>{let q=G[0],L=_.trim();if(!L)return;J.push({start:Z+G.index,end:Z+G.index+q.length,tex:L,raw:q,display:B})},Q,W=/(?<!\\)\$\$([\s\S]+?)(?<!\\)\$\$|\\\[([\s\S]+?)\\\]/g;while((Q=W.exec($))!==null)Y(Q,Q[1]??Q[2]??"",!0);let H=/\\\(([\s\S]+?)\\\)/g;while((Q=H.exec($))!==null)Y(Q,Q[1]??"",!1);let X=/(?<![\\$])\$(?!\$)([^$\n]+?)(?<![\\$])\$(?!\$)/g;while((Q=X.exec($))!==null){let G=(Q[1]??"").trim();if(pA(G))Y(Q,G,!1)}J.sort((G,_)=>G.start-_.start||_.end-G.end);let V=[],z=-1;for(let G of J){if(G.start<z)continue;V.push(G),z=G.end}return V}function cY($){let Z=l6($),J=[],Y=0;for(let Q of Z){if(Y<Q.start)J.push(...vY($.slice(Y,Q.start),Y));Y=Math.max(Y,Q.end)}if(Y<$.length)J.push(...vY($.slice(Y),Y));return J}function lA($){let Z=$;if(Z=Z.replace(/\\text\{([^{}]*)\}/g,"$1"),Z=Z.replace(/\\left\s*/g,"").replace(/\\right\s*/g,""),Z=Z.replace(/\\([A-Za-z]+)\b/g,(J,Y)=>{if(hY[Y])return hY[Y];if(Y==="times")return"×";if(Y==="cdot")return"·";if(Y==="div")return"÷";if(Y==="pm")return"±";if(Y==="leq"||Y==="le")return"≤";if(Y==="geq"||Y==="ge")return"≥";if(Y==="neq"||Y==="ne")return"≠";if(Y==="approx")return"≈";if(Y==="sim")return"~";if(Y==="infty")return"∞";if(Y==="partial")return"∂";if(Y==="nabla")return"∇";if(Y==="sqrt")return"√";if(Y==="to")return"→";return J}),/\\/.test(Z))return null;if(Z=Z.replace(/([_^])\{([^{}]+)\}/g,(J,Y,Q)=>Q.length===1?`${Y}${Q}`:`${Y}(${Q})`),Z=Z.replace(/√\{([^{}]+)\}/g,"√($1)"),/[{}]/.test(Z))return null;return Z}function aA($){let Z=gY.get($);if(Z!==void 0)return Z;return Z=dA++,gY.set($,Z),Z}function oA($,Z){return`${vA}\x00${aA(Z)}\x00${$}`}function rA($){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 tA($,Z){let J=oA($,Z),Y=Y1.get(J);if(Y)return Y;let Q=Z5.get(J);if(Q)return Q;let W=(async()=>{let H=uA($,J5,!0);if(!H)return null;let X=null;try{X=await NA(yY(xA(),"lodestar-math-"));let V=yY(X,`formula-${rA($)}.png`);await SA(V,H.png);let z=await Z(V,{tex:$,width:H.width,height:H.height});if(!z)return A(`math-render: upload returned no image key for ${$.slice(0,80)}…`),null;let G={key:z,width:H.width,height:H.height};if(Y1.has(J))Y1.delete(J);Y1.set(J,G);while(Y1.size>nA){let _=Y1.keys().next().value;if(typeof _!=="string")break;Y1.delete(_)}return G}catch(V){return A(`math-render: upload failed for ${$.slice(0,80)}…: ${V}`),null}finally{if(X)try{await kA(X,{recursive:!0,force:!0})}catch(V){A(`math-render: temp cleanup failed for ${X}: ${V}`)}}})();Z5.set(J,W);try{return await W}finally{Z5.delete(J)}}function sA($,Z,J){let Y=$.width<=fA;return{type:"image",tex:Z.tex,index:J,element:{tag:"img",img_key:$.key,alt:{tag:"plain_text",content:Z.tex.replace(/\s+/g," ").slice(0,80)},scale_type:Y?"crop_center":"fit_horizontal",...Y?{size:`${$.width}px ${$.height}px`}:{},preview:!1}}}async function mY($,Z={}){let J=cY($);if(!J.length)return{blocks:[{type:"markdown",text:$}],formulaCount:0,renderedImageCount:0};let Y=Z.uploader??iA,Q=await Promise.all(J.map(async(G)=>{if(!G.display){let _=lA(G.tex);if(_!==null)return{unicode:_,uploaded:null}}return{unicode:null,uploaded:await tA(G.tex,Y)}})),W=[],H="",X=0,V=0,z=()=>{if(!H)return;if(H.trim())W.push({type:"markdown",text:H});H=""};for(let G=0;G<J.length;G++){let _=J[G],B=Q[G];if(H+=$.slice(X,_.start),B.unicode!==null){H+=B.unicode,X=_.end;continue}let q=B.uploaded;if(!q){H+=_.raw,X=_.end;continue}z(),W.push(sA(q,_,V++)),X=_.end}if(H+=$.slice(X),z(),!W.length)W.push({type:"markdown",text:$});return{blocks:W,formulaCount:J.length,renderedImageCount:V}}function Y5($){return cY($).length>0}var Q1,bA=0.5,J5=22,xY="#1F2329",IY="#F7F8FA",$5=12,bY=8,CA=720,wA=14,fA=278,vA="v4-native-cjk-tail-pad",hA=1100,CY,gA="Noto Sans CJK SC, Noto Sans CJK JP, Microsoft YaHei, PingFang SC, Arial Unicode MS, sans-serif",wY,hY,iA=async($)=>{let{uploadImageKey:Z}=await Promise.resolve().then(() => (s(),Z0));return Z($)},gY,dA=1,Y1,Z5,nA=512;var uY=N(()=>{I();Q1=yA(import.meta.url),CY=process.platform==="win32"?"Microsoft YaHei":process.platform==="darwin"?"PingFang SC":"Noto Sans CJK SC",wY=new Map;hY={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:"Ω"};gY=new WeakMap,Y1=new Map,Z5=new Map});import{readFileSync as $_}from"node:fs";function u1($){return Q5.has($)}function l2($){Q5.add($)}function i2($){Q5.delete($)}function p1(){try{let $={};for(let[Z,J]of N0)$[Z]=J;H0(f9,$)}catch($){throw A(`notify-callbacks: save failed (${f9}): ${$}`),$}}function dY(){let $=[],Z;try{Z=$_(f9,"utf8")}catch{return[]}try{let J=JSON.parse(Z),Y=Date.now()-iY,Q=0,W=0;for(let H of Object.values(J)){if(!H||typeof H!=="object")continue;if(typeof H.notifyId!=="string"||typeof H.callbackUrl!=="string")continue;if(typeof H.createdAt!=="number"||H.createdAt<Y){Q++;continue}if(H.replyState?.status==="sending"&&!H.resolvedAt&&!H.unknownAt)H.unknownAt=Date.now(),H.unknownBy={openId:H.replyState.openId},H.unknownReason="服务在文字回复回传期间中断,无法确认是否送达,禁止自动重试",W++;if(N0.set(H.notifyId,H),H.replyState?.status==="sending"&&H.unknownAt)$.push(H)}if(A(`notify-callbacks: loaded ${N0.size} registration(s)${Q?`, dropped ${Q} stale`:""}`),W)A(`notify-callbacks: ${W} interrupted text reply(s) marked UNKNOWN`);if(Q>0||W>0)p1()}catch(J){A(`notify-callbacks: load failed (${f9}): ${J}`)}return $}function nY($){let Z=Date.now();if(Z-lY>=Z_)J_(Z),lY=Z;N0.set($.notifyId,$),p1()}function G$($){return N0.get($)}function W5($){return[...N0.values()].filter((Z)=>Z.chatId===$&&!Z.resolvedAt&&!Z.unknownAt&&(Z.replyState?.status==="waiting"||Z.replyState?.status==="sending"))}function d2($,Z){if(!$)return;return W5($).find((J)=>Z===void 0||J.replyState?.openId===Z)}function aY($,Z){return!!Z&&[...N0.values()].some((J)=>J.chatId===$&&(J.replyMessageIds?.includes(Z)||J.replyState?.response?.message_id===Z))}function l1($,Z){let J=N0.get($);if(!J)throw Error(`notify registration not found: ${$}`);let{replyState:Y,replyMessageIds:Q}=J;if(J.replyState=Z,Z.response&&!J.replyMessageIds?.includes(Z.response.message_id))J.replyMessageIds=[...J.replyMessageIds??[],Z.response.message_id];try{p1()}catch(W){if(Y)J.replyState=Y;else delete J.replyState;if(Q)J.replyMessageIds=Q;else delete J.replyMessageIds;throw W}}function n2($,Z,J){let Y=N0.get($);if(!Y)throw Error(`notify registration not found: ${$}`);let Q={resolvedAt:Y.resolvedAt,resolvedBy:Y.resolvedBy,unknownAt:Y.unknownAt,unknownBy:Y.unknownBy,unknownReason:Y.unknownReason};Y.resolvedAt=Date.now(),Y.resolvedBy={...Z!==void 0?{buttonId:Z}:{},openId:J},delete Y.unknownAt,delete Y.unknownBy,delete Y.unknownReason;try{p1()}catch(W){if(Q.resolvedAt===void 0)delete Y.resolvedAt;else Y.resolvedAt=Q.resolvedAt;if(Q.resolvedBy===void 0)delete Y.resolvedBy;else Y.resolvedBy=Q.resolvedBy;if(Q.unknownAt===void 0)delete Y.unknownAt;else Y.unknownAt=Q.unknownAt;if(Q.unknownBy===void 0)delete Y.unknownBy;else Y.unknownBy=Q.unknownBy;if(Q.unknownReason===void 0)delete Y.unknownReason;else Y.unknownReason=Q.unknownReason;throw W}}function H5($,Z,J,Y){let Q=N0.get($);if(!Q)throw Error(`notify registration not found: ${$}`);delete Q.resolvedAt,delete Q.resolvedBy,Q.unknownAt=Date.now(),Q.unknownBy={...Z!==void 0?{buttonId:Z}:{},openId:J},Q.unknownReason=Y,p1()}function v9($,Z,J){try{return n2($,Z,J),{state:"complete"}}catch(Y){let W=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{H5($,Z,J,W)}catch(H){let X=H instanceof Error?H.message:String(H);W+=`; unknown tombstone persistence also failed: ${X}`;let V=N0.get($);if(V)V.unknownReason=W}return{state:"unknown",detail:W}}}function J_($=Date.now()){let Z=$-iY,J=0;for(let[Y,Q]of N0)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)N0.delete(Y),J++;if(J>0)p1();return J}async function X5($,Z,J){let Y={notify_id:$.notifyId,message_id:$.messageId,chat_id:$.chatId,project:$.project,..."id"in Z?{button:{id:Z.id,text:Z.text,type:Z.type}}:{response:{type:"text",...Z}},operator:{open_id:J},timestamp:Math.floor(Date.now()/1000)},Q=new AbortController,W=setTimeout(()=>Q.abort(),pY);try{let H=await fetch($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Y),signal:Q.signal});if(H.status>=200&&H.status<300){let V;try{let z=(await H.text()).trim();if(z.startsWith("{")){let G=JSON.parse(z),_=typeof G?.text==="string"?G.text:typeof G?.reply==="string"?G.reply:typeof G?.message==="string"?G.message:"";if(_.trim())V=_.trim().slice(0,500)}else if(z)V=z.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:V}}let X="";try{X=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${X?` ${X}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${pY}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(W)}}function oY($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((X)=>X.id===Y):void 0,W=$.replyState?.response,H=Y!==void 0?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y}}:W?{response:{type:"text",...W}}:{};return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...$.replyState?{reply:{status:Z&&Y===void 0?"resolved":J&&Y===void 0?"unknown":$.replyState.status,prompt_message_id:$.replyState.promptMessageId,operator:{open_id:$.replyState.openId},...$.replyState.cancelReason?{cancel_reason:$.replyState.cancelReason}:{},...$.replyState.error?{error:$.replyState.error}:{}}}:{},...Z?{...H,resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{...H,unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var iY=604800000,pY=2500,N0,lY,Z_=86400000,Q5,f9;var a2=N(()=>{I();L0();I0();N0=new Map,lY=Date.now(),Q5=new Set;f9=HZ});function h9($){return[...$.pendingAsks.entries()].find(([,Z])=>Z.currentIdx!==void 0)}function i1($,Z){let J=$.pendingAsks.get(Z);if(!J||J.currentIdx===void 0)return null;if(d2($.chatId))return"请先完成或取消通知回复,再回答 Agent 的提问";if(h9($)?.[0]!==Z)return"请先回答当前问题,再回答排队中的提问";return null}function V5($,Z){let J=$.pendingAsks.get(Z);if(!J)throw Error(`missing pending ask: ${Z}`);let Y=J.currentIdx===void 0?void 0:d2($.chatId)?"notification":h9($)?.[0]!==Z?"question":void 0;return{currentIdx:J.currentIdx,answered:J.answered,waitingFor:Y}}function z5($,Z){let J=$.pendingAsks.get(Z),Y=$.currentTurn;if(!J||J.currentIdx===void 0||J.announced||i1($,Z)||!Y?.userOpenId||!Y.messageId)return;J.announced=!0;let Q=(J.announcementVersion??0)+1;J.announcementVersion=Q;let W=J.questions[J.currentIdx]?.question.trim()??"",H=W.length>40?W.slice(0,40)+"…":W,X=J.questions.length>1?`❓ 待回答 ${J.questions.length} 题${H?`: ${H}`:""}`:H?`❓ ${H}`:"❓ 等你回答问题";(async()=>{if(A0(Y.cardId),await a4(Y.cardId,{config:{summary:{content:X}}}),$.currentTurn!==Y||$.pendingAsks.get(Z)!==J||J.announcementVersion!==Q||J.currentIdx===void 0||i1($,Z))return;await n$(Y.messageId,[Y.userOpenId])})().catch((V)=>A(`session "${$.sessionName}": question notification failed: ${V}`))}function g9($){let Z=$.currentTurn;if(!Z)return;for(let[J,Y]of $.pendingAsks){let Q=Z.toolByUseId.get(J);if(!Q||Y.currentIdx===void 0)continue;let W=V5($,J);if(W.waitingFor)Y.announced=!1,Y.announcementVersion=(Y.announcementVersion??0)+1;n(Z.cardId,M.tool(Q.i),f1(Q.i,J,Y.questions,"\uD83E\uDD14",W)),z5($,J)}}function rY($){return h9($)!==void 0}async function tY($,Z,J,Y){let Q=h9($);if(!Q){A(`session "${$.sessionName}": no unanswered question; routing text to Agent`),await $.onUserMessage(Z,[],J,Y);return}let[W,H]=Q,X=i1($,W);if(X){let z=`${X}。这条文字未提交,请稍后重新发送。`;if(!await T($.chatId,z))throw Error(`提问等待提示发送失败: ${z}`);return}if(await G5($,W,H.currentIdx,Z,J)&&Y)T0(Y,"CheckMark")}async function sY($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return A(`session "${$.sessionName}": stray ask answer for ${Z}`),!1;if(J!==W.currentIdx)return A(`session "${$.sessionName}": stale ask click q=${J} current=${W.currentIdx}`),!1;return eY($,Z,{optionIdx:Y,user:Q})}async function G5($,Z,J,Y,Q){let W=$.pendingAsks.get(Z);if(!W)return A(`session "${$.sessionName}": stray ask custom for ${Z}`),!1;let H=(Y??"").trim();if(!H)return A(`session "${$.sessionName}": empty custom answer, ignoring`),!1;if(J!==W.currentIdx)return A(`session "${$.sessionName}": stale ask custom q=${J} current=${W.currentIdx}`),!1;return eY($,Z,{customText:H,user:Q})}function eY($,Z,J){let Y=$.pendingAsks.get(Z);if(!Y||Y.currentIdx===void 0)return!1;let Q=i1($,Z);if(Q)return A(`session "${$.sessionName}": ask ${Z} waiting: ${Q}`),!1;let W=Y.currentIdx,H=Y.questions[W];if(!H)return A(`session "${$.sessionName}": advanceAsk currentIdx=${W} out of range`),!1;let X;if(J.customText!==void 0)X=J.customText;else if(J.optionIdx!==void 0){let B=H.options?.[J.optionIdx];if(!B)return A(`session "${$.sessionName}": advanceAsk option ${J.optionIdx} out of range`),!1;X=B.label}else return A(`session "${$.sessionName}": advanceAsk with neither customText nor optionIdx`),!1;Y.answers[H.question]=X,Y.answered.set(W,{optionIdx:J.optionIdx,customText:J.customText,user:J.user});let V=Y.questions.length,z=void 0;for(let B=W+1;B<V;B++)if(!Y.answered.has(B)){z=B;break}Y.currentIdx=z;let G=$.currentTurn,_=G?.toolByUseId.get(Z);if(G&&_){let B=f1(_.i,Z,Y.questions,z===void 0?"✅":"\uD83E\uDD14",{currentIdx:z,answered:Y.answered});n(G.cardId,M.tool(_.i),B)}if(z===void 0)if(Y.requestId)A5($,Z);else A(`session "${$.sessionName}": ask ${Z} all answered, waiting for can_use_tool`),g9($);return!0}function A5($,Z){let J=$.pendingAsks.get(Z);if(!J||!J.requestId)return;let Y=$.currentTurn?.toolByUseId.get(Z),Q=Y?.input??{};if($.proc?.sendPermissionResponse(J.requestId,"allow",{updatedInput:{...Q,answers:J.answers}}),$.pendingPermissions.delete(J.requestId),Y)Y.output=JSON.stringify({answers:J.answers}),Y.isError=!1;if($.pendingAsks.delete(Z),g9($),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working"}var I9=N(()=>{o$();f0();s();I();a2()});import{isAbsolute as Q_}from"node:path";function K0($){if($?.planLiveInserted)return M.planLive;return $?.taskLiveInserted?M.taskBoardLive:M.footer}function W_($){return $==="ImageGeneration"||$==="imageGeneration"}function H_($,Z,J){if(J||!W_($))return null;let Y=w9(Z.trim());return Q_(Y)?Y:null}function X_($){if($==="Read")return"read";if($==="Edit"||$==="MultiEdit"||$==="NotebookEdit")return"edit";return null}function $Q($,Z,J){return $==="read"?f2(Z,J):w2(Z,J)}function ZQ($,Z,J,Y){if(!$.currentTurn)return;if($.maybeMidTurnRotate(),$.startWorkingFooter($.currentTurn),$.currentTurn.currentAssistantSegmentId)$.finalizeCurrentAssistantSegment();let Q=X_(J);if(Q&&$.currentTurn.openBatchI!==null){let V=$.currentTurn.openBatchI,z=$.currentTurn.toolBatches.get(V);if(z&&z.kind===Q){let G=z.items.length;z.items.push({toolUseId:Z,input:Y,output:null,isError:!1}),$.currentTurn.toolByUseId.set(Z,{i:V,name:J,input:Y,batchSlot:G});let _=Q==="read"?f2(V,z.items):w2(V,z.items);n($.currentTurn.cardId,M.tool(V),_),c9($.currentTurn,J,Y);return}}if(!Q)$.currentTurn.openBatchI=null;let W=$1(J);if(W){let V=$.currentTurn;if(W==="TaskCreate"&&!V.taskBoardResetThisTurn)$.taskBoard=[],V.taskBoardResetThisTurn=!0;if(!V.taskLiveInserted)V.taskLiveInserted=!0,X0(V.cardId,Z1($.taskBoard),{type:"insert_before",targetElementId:M.footer});else n(V.cardId,M.taskBoardLive,Z1($.taskBoard));let z=W==="TaskCreate";if(z)V.taskUpdateI=null;else V.taskCreateI=null;let G=(z?V.taskCreateI:V.taskUpdateI)===null;if(G)if(z)V.taskCreateI=V.toolCount++;else V.taskUpdateI=V.toolCount++;let _=z?V.taskCreateI:V.taskUpdateI;V.toolByUseId.set(Z,{i:_,name:J,input:Y});let B=k$(_,$.taskBoard,{name:W,status:"⏳"});G?X0(V.cardId,B,{type:"insert_before",targetElementId:K0(V)}):n(V.cardId,M.tool(_),B),c9(V,J,Y);return}$.currentTurn.taskCreateI=null,$.currentTurn.taskUpdateI=null;let H=$.currentTurn.toolCount++;if(Q){$.currentTurn.openBatchI=H;let V=[{toolUseId:Z,input:Y,output:null,isError:!1}];$.currentTurn.toolBatches.set(H,{kind:Q,items:V}),$.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y,batchSlot:0});let z=Q==="read"?f2(H,V):w2(H,V);X0($.currentTurn.cardId,z,{type:"insert_before",targetElementId:K0($.currentTurn)}),c9($.currentTurn,J,Y);return}if($.currentTurn.toolByUseId.set(Z,{i:H,name:J,input:Y}),J==="AskUserQuestion"){let V=Array.isArray(Y?.questions)?Y.questions:[],z=V.length>0?0:void 0,G=new Map;$.pendingAsks.set(Z,{questions:V,i:H,answers:{},answered:G,currentIdx:z});let _=f1(H,Z,V,"\uD83E\uDD14",V5($,Z));X0($.currentTurn.cardId,_,{type:"insert_before",targetElementId:K0($.currentTurn)}),z5($,Z);return}let X=O$(H,J,Y,null,"⏳");X0($.currentTurn.cardId,X,{type:"insert_before",targetElementId:K0($.currentTurn)}),c9($.currentTurn,J,Y)}function c9($,Z,J){if(!$)return;let Y=F$(Z,J),Q=Y.length>80?Y.slice(0,80)+"…":Y,W=r$(Z),H=Q?`\uD83D\uDD27 ${W}: ${Q}`:`\uD83D\uDD27 ${W}`;H$($.cardId,H)}function JQ($,Z,J,Y){if(!$.currentTurn)return;let Q=$.currentTurn.toolByUseId.get(Z);if(!Q)return;let W=typeof J==="string"?J:Array.isArray(J)?J.map((z)=>z?.text??JSON.stringify(z)).join(`
156
+ `):JSON.stringify(J);if(Q.output=W,Q.isError=Y,$.currentTurn.cardRotationFailed)$.maybeMidTurnRotate();let H=H_(Q.name,W,Y);if(H)$.sendOutboundPath(H,Q.name);if(Q.name==="AskUserQuestion"){m9($);return}if(Q.batchSlot!=null){let z=$.currentTurn.toolBatches.get(Q.i);if(z){let G=z.items[Q.batchSlot];if(G)G.output=W,G.isError=Y;let _=$Q(z.kind,Q.i,z.items);n($.currentTurn.cardId,M.tool(Q.i),_)}m9($);return}let X=$1(Q.name);if(X){V_($,Q,X,Q.input,W,Y,Q.resolvedNote);return}let V=O$(Q.i,Q.name,Q.input,W,Y?"❌":"✅",Q.resolvedNote);n($.currentTurn.cardId,M.tool(Q.i),V),m9($)}function V_($,Z,J,Y,Q,W,H){if(!$.currentTurn)return;if(!W)$.taskBoard=l8($.taskBoard,J,Y,Q);let X=k$(Z.i,$.taskBoard,{name:J,status:W?"❌":"✅"},H);if(n($.currentTurn.cardId,M.tool(Z.i),X),$.currentTurn.taskLiveInserted)n($.currentTurn.cardId,M.taskBoardLive,Z1($.taskBoard));m9($)}function m9($){let Z=$.currentTurn;if(!Z)return;for(let J of Z.toolByUseId.values())if(J.output==null)return;$.startThinkingFooter(Z)}function _5($,Z,J,Y,Q,W=$.currentTurn){let H=W;if(!H)return;for(let[X,V]of Y){if(H.toolByUseId.has(X))continue;let z=V.batchSlot??null,G=V.input,_,B;if(z!=null){let j=Q.get(V.i)?.items[z];if(!j)continue;G=j.input,_=j.output,B=j.isError}else _=V.output??null,B=V.isError??!1;let q=_!=null,L=C1(Z,M.tool(V.i));if(q&&!L)continue;if(z!=null){let j=Q.get(V.i)?.kind;if(!j)continue;let D=H.toolCount++,E={toolUseId:X,input:G,output:_,isError:B};H.toolBatches.set(D,{kind:j,items:[E]}),H.toolByUseId.set(X,{...V,i:D,batchSlot:0}),X0(J,$Q(j,D,[E]),{type:"insert_before",targetElementId:K0(H)});continue}let P=$1(V.name);if(P){let j=P==="TaskCreate";if(j)H.taskUpdateI=null;else H.taskCreateI=null;let D=(j?H.taskCreateI:H.taskUpdateI)===null;if(D)if(j)H.taskCreateI=H.toolCount++;else H.taskUpdateI=H.toolCount++;let E=j?H.taskCreateI:H.taskUpdateI;H.toolByUseId.set(X,{...V,i:E});let x=!q?"⏳":B?"❌":"✅",b=k$(E,$.taskBoard,{name:P,status:x},V.resolvedNote);D?X0(J,b,{type:"insert_before",targetElementId:K0(H)}):n(J,M.tool(E),b);continue}let R=H.toolCount++;H.toolByUseId.set(X,{...V,i:R});let O=!q?"⏳":B?"❌":"✅";X0(J,O$(R,V.name,V.input,_,O,V.resolvedNote),{type:"insert_before",targetElementId:K0(H)})}}var YQ=N(()=>{t8();o$();f0();I9()});async function QQ($,Z,J,Y){let Q=$.pendingPermissions.get(Z);if(!Q)return A(`session "${$.sessionName}": stray permission ${Z}`),{ok:!1,message:"此权限请求已失效或已处理"};let W=$.proc;if(!W)return A(`session "${$.sessionName}": permission ${Z} has no active process`),{ok:!1,message:"后端进程已退出,权限决定未送达"};let H=J==="deny"?"deny":"allow";try{W.sendPermissionResponse(Z,H,J==="allow_always"?{updatedPermissions:Q.permissionSuggestions}:void 0)}catch(z){return A(`session "${$.sessionName}": permission response ${Z} failed: ${z}`),{ok:!1,message:`权限决定发送失败: ${z instanceof Error?z.message:z}`}}$.pendingPermissions.delete(Z);let X=$.currentTurn,V=X?.toolByUseId.get(Q.toolUseId);if(X&&V){let z=$1(V.name);if(J==="deny"){let G=`\uD83D\uDEAB 已拒绝 by ${Y||"匿名"}`,_=z?k$(V.i,$.taskBoard,{name:z,status:"❌"},G):O$(V.i,V.name,V.input,G,"❌");n(X.cardId,M.tool(V.i),_)}else{let G=J==="allow_always"?"始终允许":"已允许";V.resolvedNote=`✅ **${G}** by ${Y||"匿名"}`;let _=z?k$(V.i,$.taskBoard,{name:z,status:"⏳"},V.resolvedNote):O$(V.i,V.name,V.input,null,"⏳",V.resolvedNote);n(X.cardId,M.tool(V.i),_)}}if(A(`session "${$.sessionName}": permission decision request=${Z} tool_use_id=${Q.toolUseId} decision=${J}`),$.pendingPermissions.size===0&&$.status==="awaiting_permission")$.status="working";return{ok:!0,message:J==="deny"?"已拒绝":J==="allow_always"?"已始终允许":"已允许"}}function WQ($,Z){let J=$.currentTurn;if(!J){A(`session "${$.sessionName}": can_use_tool with no current turn — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no active turn"});return}let Y=Z.tool_use_id;if(!Y){A(`session "${$.sessionName}": can_use_tool without tool_use_id — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no tool_use_id"});return}let Q=J.toolByUseId.get(Y);if(!Q){A(`session "${$.sessionName}": can_use_tool for unknown tool_use_id=${Y} — auto-deny req=${Z.request_id}`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"unknown tool_use_id"});return}if(Q.name==="AskUserQuestion"){let H=$.pendingAsks.get(Y);if(!H){A(`session "${$.sessionName}": AskUserQuestion ${Y} missing pendingAsk — deny`),$.proc?.sendPermissionResponse(Z.request_id,"deny",{denyMessage:"no pending ask"});return}if(H.requestId=Z.request_id,$.pendingPermissions.set(Z.request_id,{toolUseId:Y}),H.currentIdx===void 0)A5($,Y);return}$.status="awaiting_permission",$.pendingPermissions.set(Z.request_id,{toolUseId:Y,permissionSuggestions:Z.permission_suggestions}),A(`session "${$.sessionName}": can_use_tool request=${Z.request_id} tool_use_id=${Y} tool=${Q.name}`);let W=R8(Q.i,Q.name,Q.input,Z.request_id);if(n(J.cardId,M.tool(Q.i),W),J.userOpenId&&J.messageId){let H=F$(Q.name,Q.input),X=r$(Q.name),V=H&&H.length>30?H.slice(0,30)+"…":H,z=V?`\uD83D\uDD10 等审批: ${X} · ${V}`:`\uD83D\uDD10 等审批: ${X}`;(async()=>{A0(J.cardId),await a4(J.cardId,{config:{summary:{content:z}}}),await n$(J.messageId,[J.userOpenId])})()}}var HQ=N(()=>{o$();f0();s();I();I9()});function XQ($,Z=zQ){return new Promise((J,Y)=>{let Q=setTimeout(()=>Y(Error(`timeout ${Z}ms`)),Z);$.then((W)=>{clearTimeout(Q),J(W)},(W)=>{clearTimeout(Q),Y(W)})})}function VQ($){return typeof $==="string"&&A_.includes($)?$:null}async function GQ(){let $=new S9;try{await XQ($.request("initialize",{clientInfo:{name:"lodestar-models",version:"0.0.0"},capabilities:{experimentalApi:!0,requestAttestation:!1}}));let Z=await XQ($.request("model/list",{})),J=Array.isArray(Z?.data)?Z.data:[],Y=[];for(let Q of J){if(!Q||Q.hidden||!Q.id)continue;let W=(Array.isArray(Q.supportedReasoningEfforts)?Q.supportedReasoningEfforts:[]).map((X)=>VQ(X?.reasoningEffort)).filter((X)=>X!==null);if(!W.length)continue;let H=VQ(Q.defaultReasoningEffort)??W[0];Y.push({model:String(Q.id),display:typeof Q.displayName==="string"&&Q.displayName?String(Q.displayName):String(Q.id),efforts:W,defaultEffort:H})}return Y}finally{await $.close()}}async function AQ($,Z){let J=new URL($),Y=J.pathname.replace(/\/+$/,""),Q=`${J.protocol}//${J.host}${Y}/v1/models`,W=await fetch(Q,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(zQ)});if(!W.ok)throw Error(`HTTP ${W.status}`);let H=await W.json();return(Array.isArray(H?.data)?H.data:[]).filter((V)=>V&&(V.display_name||V.id)).map((V)=>{let z=String(V.display_name||V.id);return{model:z,display:z,efforts:d0,defaultEffort:"max"}})}var zQ=1e4,A_,d0;var o2=N(()=>{x9();A_=["none","minimal","low","medium","high","xhigh","max","ultra"];d0=["max","xhigh","high","medium","low"]});import{existsSync as __}from"node:fs";import{homedir as K_}from"node:os";import{join as _Q}from"node:path";function u9($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function B_($){if($.state!=="ok")return{state:$.state==="auth_failed"?"no_credentials":$.state==="no_credentials"?"no_credentials":$.state==="rate_limited"?"rate_limited":"network",windows:[]};let Z=[];if($.fiveHour)Z.push(u9($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(u9($.weekly,"weekly","周配额"));return{state:"ok",planLabel:$.subscriptionType,windows:Z,fetchedAt:$.fetchedAt}}function q_($){if($.state!=="ok"||!$.buckets?.length)return null;let Z=[];for(let J of $.buckets){let Y=J.limitId===$.defaultLimitId?J.limitName??"默认配额":J.limitName??J.limitId;if(J.fiveHour)Z.push(u9(J.fiveHour,"fiveHour",`${Y} 5h`));if(J.weekly)Z.push(u9(J.weekly,"weekly",`${Y} 周`))}return Z.length?Z:null}function L_(){let $=process.env.CODEX_HOME||_Q(K_(),".codex");return __(_Q($,"auth.json"))}var KQ=N(()=>{U0();G0();x9();o2();I();Y$({kind:"codex-subscription",configSectionId:"codex-sub",build:($)=>{let Z=L_(),J=$.model?.trim()||void 0,Y=$.effort?.trim()||void 0,Q={id:"codex-sub",kind:"codex-subscription",agent:"codex",display:$.display?.trim()||"Codex 订阅",enabled:Z,models:[],modelCatalogState:{status:Z?"idle":"disabled",updatedAt:Date.now()},defaultModel:J??"",async refreshModels(){if(!Q.enabled){Q.models=[],Q.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}Q.modelCatalogState={status:"loading",updatedAt:null};try{if(Q.models=await GQ(),Y)for(let W of Q.models)W.defaultEffort=Y;if(!J)Q.defaultModel=Q.models[0]?.model??"";Q.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(W){A(`codex-sub refreshModels MISS: ${W?.message??W}`),Q.models=[],Q.modelCatalogState={status:"failed",updatedAt:Date.now(),error:W?.message??String(W)}}},spawnEnv(W){let H=m$(W);return Object.assign(H,v.codex.env),H},resolveSpawnModel(W){return W},async readUsage(){let W=await y9(),H=B_(W),X=q_(W);if(X)H.windows=X;return H}};return Q}})});function j_($){let Z=new URL($),J=Z.pathname.replace(/\/+$/,"");return`${Z.protocol}//${Z.host}${J}/v1/messages`}async function p9($,Z,J){try{let Y=await fetch(j_($),{method:"POST",headers:{"Content-Type":"application/json",...Z},body:JSON.stringify({model:J,max_tokens:1,messages:[{role:"user",content:"hi"}]}),signal:AbortSignal.timeout(P_)});if(Y.ok)return"exists";if(Y.status===400){let Q=await Y.text();return Q.includes("1214")||Q.includes("不存在")||Q.includes("not exist")?"not_found":"no_verdict"}return A(`model-existence: ${J} HTTP ${Y.status}, no verdict`),"no_verdict"}catch(Y){return A(`model-existence: ${J} MISS (${Y?.message??Y})`),"no_verdict"}}var P_=15000;var K5=N(()=>{I()});function BQ($,Z,J){return{kind:Z,label:J,percent:$.percent,resetsAt:$.resetsAt}}function R_($){return{kind:"monthly",label:"月度工具",percent:$.percent,resetsAt:$.resetsAt,...$.used!=null?{used:$.used}:{},...$.total!=null?{total:$.total}:{}}}function D_($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function M_($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function F_($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function U_($){if($.state!=="ok")return{state:$.state==="no_credentials"?"no_credentials":$.state==="not_glm"?"not_applicable":$.state==="rate_limited"?"rate_limited":"network",windows:[],...$.state==="network"&&$.reason?{reason:$.reason}:{}};let Z=[];if($.fiveHour)Z.push(BQ($.fiveHour,"fiveHour","5h 窗口"));if($.weekly)Z.push(BQ($.weekly,"weekly","周额度"));if($.monthly)Z.push(R_($.monthly));return{state:"ok",planLabel:$.level?`${$.level} 套餐`:void 0,windows:Z,fetchedAt:$.fetchedAt}}var qQ=N(()=>{G0();C9();o2();N4();K5();I();Y$({kind:"glm-coding-plan",configSectionId:"glm",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||"",Y=$.auth_token?.trim()||Z?.auth_token?.trim()||"",Q=!!(J&&Y)&&b9(J),W=$.model?.trim()||void 0,H=F_($.slots),X={id:"glm",kind:"glm-coding-plan",agent:"claude",display:$.display?.trim()||"GLM Coding Plan",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let V=await AQ(J,Y),G=D_($.models).filter((_)=>!V.some((B)=>B.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:d0,defaultEffort:"max"}));if(X.models=[...V,...G],!W)X.defaultModel=M_(X.models.map((_)=>_.model));for(let _ of X.models){let B=T4("glm",_.model);_.context1m=B!=null&&B>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){A(`glm refreshModels MISS: ${V?.message??V}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V?.message??String(V)}}},spawnEnv(V){let G={...m$(V)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_AUTH_TOKEN=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(V){return E4("glm",V)},async verifyModel(V){return p9(J,{Authorization:`Bearer ${Y}`},V)},async readUsage(){return U_(await o8(J,Y))}};return X},setup:{commandSuffix:"glm",hint:($)=>`启用 ${$}:发送
157
157
  \`\`\`
158
158
  glm-setup <base_url> <token>
159
- \`\`\``,parseArgs:($)=>{let Z=$.trim().split(/\s+/);if(Z.length<2)return{error:"用法:`glm-setup <base_url> <token>`"};return{config:{agent:"claude",base_url:Z[0],auth_token:Z[1]}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!F6(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var nY;var aY=S(()=>{G$();g2();nY=[{model:"fable",display:"Fable",efforts:i$,defaultEffort:"max"},{model:"opus",display:"Opus",efforts:i$,defaultEffort:"high"},{model:"sonnet",display:"Sonnet",efforts:i$,defaultEffort:"medium"},{model:"haiku",display:"Haiku",efforts:i$,defaultEffort:"medium"}];J0({kind:"claude-native",build:($)=>{let Z={id:"claude-native",kind:"claude-native",agent:"claude",display:"Claude",enabled:!1,models:nY,modelCatalogState:{status:"ready",updatedAt:Date.now()},defaultModel:"opus",settingSources:["user","project","local"],async refreshModels(){Z.models=nY,Z.modelCatalogState={status:Z.enabled?"ready":"disabled",updatedAt:Date.now()}},spawnEnv(J){return J},resolveSpawnModel(J){return J},async readUsage(){return{state:"not_applicable",windows:[]}}};return Z}})});function HK($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function XK($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function VK($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function zK($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function GK($,Z){let J=new URL($).origin,Y=await fetch(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json();return(Array.isArray(Q?.data)?Q.data:[]).filter((H)=>H&&typeof H.id==="string"&&H.id).map((H)=>({model:H.id,display:H.id,efforts:i$,defaultEffort:"high"}))}async function KK($,Z){let J;try{J=new URL($).origin}catch{return{state:"network",windows:[],reason:"bad base_url"}}try{let Y=await fetch(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(AK)});if(!Y.ok)return{state:"network",windows:[],reason:`HTTP ${Y.status}`};let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof H?.currency==="string"?H.currency:"",V=X==="CNY"?"¥":X==="USD"?"$":X?`${X} `:"",z=H?.total_balance;if(typeof z!=="string"&&typeof z!=="number")return{state:"ok",windows:[],planLabel:"余额 —(无明细)"};let A=Q?.is_available!==!1;return{state:"ok",windows:[],planLabel:A?`剩余 ${V}${z}`:`⚠️ 余额不足 ${V}${z}`}}catch(Y){return G(`deepseek readUsage MISS: ${Y?.message??Y}`),{state:"network",windows:[],reason:Y?.message??String(Y)}}}var WK="https://api.deepseek.com/anthropic",AK=1e4;var oY=S(()=>{G$();g2();P4();a7();g();J0({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||WK,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,W=$.model?.trim()||void 0,H=VK($.slots),X={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let V=await GK(J,Y),A=HK($.models).filter((K)=>!V.some((B)=>B.model.toLowerCase()===K.toLowerCase())).map((K)=>({model:K,display:K,efforts:i$,defaultEffort:"high"}));if(X.models=[...V,...A],!W)X.defaultModel=XK(X.models.map((K)=>K.model));for(let K of X.models){let B=L4("deepseek",K.model);K.context1m=B!=null&&B>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){G(`deepseek refreshModels MISS: ${V?.message??V}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V?.message??String(V)}}},spawnEnv(V){let A={...g0(V)};if(A.ANTHROPIC_BASE_URL=J,A.ANTHROPIC_API_KEY=Y,H.opus)A.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)A.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)A.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return A},resolveSpawnModel(V){return R4("deepseek",V)},async verifyModel(V){return k6(J,{"x-api-key":Y},V)},async readUsage(){if(!Y)return{state:"no_credentials",windows:[]};return KK(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
159
+ \`\`\``,parseArgs:($)=>{let Z=$.trim().split(/\s+/);if(Z.length<2)return{error:"用法:`glm-setup <base_url> <token>`"};return{config:{agent:"claude",base_url:Z[0],auth_token:Z[1]}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!b9(Z))return null;let J=$.ANTHROPIC_AUTH_TOKEN?.trim()??"";return J?{base_url:Z,auth_token:J}:null}}})});var LQ;var PQ=N(()=>{G0();o2();LQ=[{model:"fable",display:"Fable",efforts:d0,defaultEffort:"max"},{model:"opus",display:"Opus",efforts:d0,defaultEffort:"high"},{model:"sonnet",display:"Sonnet",efforts:d0,defaultEffort:"medium"},{model:"haiku",display:"Haiku",efforts:d0,defaultEffort:"medium"}];Y$({kind:"claude-native",build:($)=>{let Z={id:"claude-native",kind:"claude-native",agent:"claude",display:"Claude",enabled:!1,models:LQ,modelCatalogState:{status:"ready",updatedAt:Date.now()},defaultModel:"opus",settingSources:["user","project","local"],async refreshModels(){Z.models=LQ,Z.modelCatalogState={status:Z.enabled?"ready":"disabled",updatedAt:Date.now()}},spawnEnv(J){return J},resolveSpawnModel(J){return J},async readUsage(){return{state:"not_applicable",windows:[]}}};return Z}})});function E_($){return($??"").split(",").map((Z)=>Z.trim()).filter(Boolean)}function T_($){let Z=(J)=>{let Y=J.match(/(\d+(?:\.\d+)?)/);return Y?Number(Y[1]):-1};return[...$].sort((J,Y)=>Z(Y)-Z(J))[0]??""}function N_($){let Z={};for(let J of($??"").split(",")){let Y=J.indexOf("=");if(Y<=0)continue;let Q=J.slice(0,Y).trim().toLowerCase(),W=J.slice(Y+1).trim();if((Q==="opus"||Q==="sonnet"||Q==="haiku")&&W)Z[Q]=W}return Z}function k_($){try{return new URL($).hostname.toLowerCase()==="api.deepseek.com"}catch{return!1}}async function S_($,Z){let J=new URL($).origin,Y=await fetch(`${J}/models`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(1e4)});if(!Y.ok)throw Error(`HTTP ${Y.status}`);let Q=await Y.json();return(Array.isArray(Q?.data)?Q.data:[]).filter((H)=>H&&typeof H.id==="string"&&H.id).map((H)=>({model:H.id,display:H.id,efforts:d0,defaultEffort:"high"}))}async function x_($,Z){let J;try{J=new URL($).origin}catch{return{state:"network",windows:[],reason:"bad base_url"}}try{let Y=await fetch(`${J}/user/balance`,{headers:{Authorization:`Bearer ${Z}`},signal:AbortSignal.timeout(y_)});if(!Y.ok)return{state:"network",windows:[],reason:`HTTP ${Y.status}`};let Q=await Y.json(),H=(Array.isArray(Q?.balance_infos)?Q.balance_infos:[])[0],X=typeof H?.currency==="string"?H.currency:"",V=X==="CNY"?"¥":X==="USD"?"$":X?`${X} `:"",z=H?.total_balance;if(typeof z!=="string"&&typeof z!=="number")return{state:"ok",windows:[],planLabel:"余额 —(无明细)"};let G=Q?.is_available!==!1;return{state:"ok",windows:[],planLabel:G?`剩余 ${V}${z}`:`⚠️ 余额不足 ${V}${z}`}}catch(Y){return A(`deepseek readUsage MISS: ${Y?.message??Y}`),{state:"network",windows:[],reason:Y?.message??String(Y)}}}var O_="https://api.deepseek.com/anthropic",y_=1e4;var jQ=N(()=>{G0();o2();N4();K5();I();Y$({kind:"deepseek",configSectionId:"deepseek",build:($,Z)=>{let J=$.base_url?.trim()||Z?.base_url?.trim()||O_,Y=$.api_key?.trim()||Z?.api_key?.trim()||"",Q=!!Y,W=$.model?.trim()||void 0,H=N_($.slots),X={id:"deepseek",kind:"deepseek",agent:"claude",display:$.display?.trim()||"DeepSeek",enabled:Q,models:[],modelCatalogState:{status:Q?"idle":"disabled",updatedAt:Date.now()},defaultModel:W??"",async refreshModels(){if(!X.enabled){X.models=[],X.modelCatalogState={status:"disabled",updatedAt:Date.now()};return}X.modelCatalogState={status:"loading",updatedAt:null};try{let V=await S_(J,Y),G=E_($.models).filter((_)=>!V.some((B)=>B.model.toLowerCase()===_.toLowerCase())).map((_)=>({model:_,display:_,efforts:d0,defaultEffort:"high"}));if(X.models=[...V,...G],!W)X.defaultModel=T_(X.models.map((_)=>_.model));for(let _ of X.models){let B=T4("deepseek",_.model);_.context1m=B!=null&&B>=1e6||void 0}X.modelCatalogState={status:"ready",updatedAt:Date.now()}}catch(V){A(`deepseek refreshModels MISS: ${V?.message??V}`),X.models=[],X.modelCatalogState={status:"failed",updatedAt:Date.now(),error:V?.message??String(V)}}},spawnEnv(V){let G={...m$(V)};if(G.ANTHROPIC_BASE_URL=J,G.ANTHROPIC_API_KEY=Y,H.opus)G.ANTHROPIC_DEFAULT_OPUS_MODEL=H.opus;if(H.sonnet)G.ANTHROPIC_DEFAULT_SONNET_MODEL=H.sonnet;if(H.haiku)G.ANTHROPIC_DEFAULT_HAIKU_MODEL=H.haiku;return G},resolveSpawnModel(V){return E4("deepseek",V)},async verifyModel(V){return p9(J,{"x-api-key":Y},V)},async readUsage(){if(!Y)return{state:"no_credentials",windows:[]};return x_(J,Y)}};return X},setup:{commandSuffix:"deepseek",hint:($)=>`启用 ${$}:发送
160
160
  \`\`\`
161
161
  deepseek-setup <api_key>
162
162
  \`\`\`
163
- 默认官方 Anthropic 端点;自建中转用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length)return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Y=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Y}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!zK(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});var tY={};G1(tY,{tokenSourceSpawnRevision:()=>rY,buildTokenSourcesFromConfig:()=>o7});import{createHash as _K}from"node:crypto";function o7(){Q8();let $=f7(),Z=U1().map((W)=>{let H=W.configSectionId?(v.token_sources??{})[W.configSectionId]??{}:{},X=W.detect?.fromSettingsEnv($)??null,V=W.build(H,X);return V.spawnRevision=rY(W.kind,H,X),V}),J=Z.find((W)=>W.kind==="claude-native");if(J){let W=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!W,J.modelCatalogState={status:J.enabled?"ready":"disabled",updatedAt:Date.now()}}for(let W of Z)J8(W);let Q=Z.find((W)=>W.enabled&&v.token_sources?.[W.id]?.default===!0)??Z.find((W)=>W.enabled);if(Q)Y8(Q.id);return Z.length}function rY($,Z,J){let Y=(Q)=>({agent:Q?.agent,auth:Q?.auth,base_url:Q?.base_url,auth_token:Q?.auth_token,api_key:Q?.api_key,bin:Q?.bin,model:Q?.model,effort:Q?.effort,slots:Q?.slots});return _K("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var r7=S(()=>{U$();G$();U6();lY();dY();aY();oY()});import{readFileSync as BK}from"node:fs";function qK($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function RK($,Z){let J=[`[token_source.${$}]`],Y=(Q,W)=>{if(W&&W.length)J.push(`${Q} = "${qK(W)}"`)};if(Y("agent",Z.agent),Y("display",Z.display),Y("auth",Z.auth),Y("base_url",Z.base_url),Y("auth_token",Z.auth_token),Y("api_key",Z.api_key),Y("bin",Z.bin),Y("model",Z.model),Y("effort",Z.effort),Y("models",Z.models),Y("slots",Z.slots),Y("usage",Z.usage),Z.default)J.push('default = "true"');return J.join(`
164
- `)}async function S6($,Z){let J=BK(q$,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
165
- `),W=!1,H={},X=[];for(let K of Q){let B=K.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(B)W=B===Y;if(W){let q=K.match(/^\s*([A-Za-z_]+)\s*=\s*"([^"]*)"/);if(q)H[q[1]]=q[2]}else X.push(K)}let V={...H},z={...Z};for(let K of Object.keys(z))if(z[K])V[K]=z[K];let A=V;while(X.length&&X[X.length-1]==="")X.pop();h$(q$,X.join(`
163
+ 默认官方 Anthropic 端点;自建中转用 \`deepseek-setup <base_url> <api_key>\`。`,parseArgs:($)=>{let Z=$.trim().split(/\s+/).filter(Boolean);if(!Z.length)return{error:"用法:`deepseek-setup <api_key>`(官方端点)或 `deepseek-setup <base_url> <api_key>`(自建中转)"};let J=Z.length>=2?Z[0]:void 0,Y=Z.length>=2?Z[1]:Z[0];return{config:{agent:"claude",...J?{base_url:J}:{},api_key:Y}}}},detect:{fromSettingsEnv($){let Z=$.ANTHROPIC_BASE_URL?.trim()??"";if(!k_(Z))return null;let J=$.ANTHROPIC_API_KEY?.trim()??"";return J?{base_url:Z,api_key:J}:null}}})});var DQ={};B1(DQ,{tokenSourceSpawnRevision:()=>RQ,buildTokenSourcesFromConfig:()=>B5});import{createHash as b_}from"node:crypto";function B5(){j7();let $=a8(),Z=N1().map((W)=>{let H=W.configSectionId?(v.token_sources??{})[W.configSectionId]??{}:{},X=W.detect?.fromSettingsEnv($)??null,V=W.build(H,X);return V.spawnRevision=RQ(W.kind,H,X),V}),J=Z.find((W)=>W.kind==="claude-native");if(J){let W=Z.some((H)=>H.agent==="claude"&&H.enabled&&H.kind!=="claude-native");J.enabled=!W,J.modelCatalogState={status:J.enabled?"ready":"disabled",updatedAt:Date.now()}}for(let W of Z)L7(W);let Q=Z.find((W)=>W.enabled&&v.token_sources?.[W.id]?.default===!0)??Z.find((W)=>W.enabled);if(Q)P7(Q.id);return Z.length}function RQ($,Z,J){let Y=(Q)=>({agent:Q?.agent,auth:Q?.auth,base_url:Q?.base_url,auth_token:Q?.auth_token,api_key:Q?.api_key,bin:Q?.bin,model:Q?.model,effort:Q?.effort,slots:Q?.slots});return b_("sha256").update(JSON.stringify({kind:$,configured:Y(Z),detected:Y(J)})).digest("hex")}var q5=N(()=>{U0();G0();C9();KQ();qQ();PQ();jQ()});import{readFileSync as C_}from"node:fs";function w_($){return $.replace(/\\/g,"\\\\").replace(/"/g,"\\\"")}function f_($,Z){let J=[`[token_source.${$}]`],Y=(Q,W)=>{if(W&&W.length)J.push(`${Q} = "${w_(W)}"`)};if(Y("agent",Z.agent),Y("display",Z.display),Y("auth",Z.auth),Y("base_url",Z.base_url),Y("auth_token",Z.auth_token),Y("api_key",Z.api_key),Y("bin",Z.bin),Y("model",Z.model),Y("effort",Z.effort),Y("models",Z.models),Y("slots",Z.slots),Y("usage",Z.usage),Z.default)J.push('default = "true"');return J.join(`
164
+ `)}async function l9($,Z){let J=C_(q0,"utf8"),Y=`[token_source.${$}]`,Q=J.split(`
165
+ `),W=!1,H={},X=[];for(let _ of Q){let B=_.match(/^\s*(\[[^\]]+\])\s*(?:#.*)?$/)?.[1];if(B)W=B===Y;if(W){let q=_.match(/^\s*([A-Za-z_]+)\s*=\s*"([^"]*)"/);if(q)H[q[1]]=q[2]}else X.push(_)}let V={...H},z={...Z};for(let _ of Object.keys(z))if(z[_])V[_]=z[_];let G=V;while(X.length&&X[X.length-1]==="")X.pop();g0(q0,X.join(`
166
166
  `)+`
167
167
 
168
- `+RK($,A)+`
169
- `),XZ(),o7(),await z2()}var t7=S(()=>{R$();U$();r7();G$();g$()});var s7={};G1(s7,{runTokenSourceSetup:()=>PK,onTokenSourceEnable:()=>LK});async function LK($,Z){let J=e(Z);if(!J){await N($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await N($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=U1().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup)await N($.chatId,Y.setup.hint(J.display));else if(J.kind==="codex-subscription")await N($.chatId,`${J.display} 需要 ChatGPT 登录:在服务器执行 \`codex login\`,完成后按当前服务管理方式重启 daemon,或重发 \`model\` 刷新。`);else if(J.kind==="claude-native")await N($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function PK($,Z,J){let Y=U1().find((W)=>W.setup?.commandSuffix===Z);if(!Y?.setup||!Y.configSectionId){await N($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Q=Y.setup.parseArgs(J);if("error"in Q){await N($.chatId,Q.error);return}try{await S6(Y.configSectionId,Q.config);let W=e(Y.configSectionId);await N($.chatId,`✅ ${W?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(W){await N($.chatId,`❌ 启用失败: ${W?.message??W}`)}}var e7=S(()=>{o();G$();t7()});async function sY($,Z,J=""){let Y=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(Y)return await $.runWorktreeCommand((Y[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let Q=Z.trim().match(/^(\w+)-setup\s+([\s\S]+)$/i);if(Q){let{runTokenSourceSetup:H}=await Promise.resolve().then(() => (e7(),s7));return await H($,Q[1].trim(),Q[2].trim()),!0}let W=DK.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 X=!$.isRunning(),V=$.backendLabel(),z=X?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${V}`)):null,A=$.withModel(`\uD83D\uDE80 启动 ${V}`);if(!(X?await $.start({announce:!z,onStatus:(B)=>{A=B,$.setStatusCard(z,B)}}):!0))return await $.closeStatusCard(z,A.startsWith("❌")?A:"❌ 启动失败"),!0;if(z)return await $.replaceStatusCardWithConsole(z,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(X)await $.closeStatusCard(z,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let X=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(X)await $.closeStatusCard(X,"⚪ 无正在执行的 turn");else await N($.chatId,"⚪ 当前没有正在执行的 turn");return!0}G(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let H=new Set;for(let[X,V]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(V)P$(X,V);T$(X,"CrossMark"),H.add(X)}for(let X of $.pendingMidTurnMsgs)if(X.msgId&&!H.has(X.msgId))T$(X.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0;case"kill":{let X=$.isRunning(),V=$.backendLabel($.proc?.provider??$.currentProvider()),z=X?`\uD83D\uDED1 停止 ${V}`:"⚪ session 当前未运行",A=await $.openStatusCard("kill",z,X?"red":"grey"),K=null,B=X?`✅ ${V} 已终止`:`⚪ ${V} 未运行`;try{await $.stop("已终止",{announce:!A,onStatus:(q)=>{$.setStatusCard(A,q)}})}catch(q){K=q,B=$.isRunning()?`❌ ${V} 未确认终止: ${F(q)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${V} 停止收尾失败: ${F(q)}`}finally{try{await $.closeStatusCard(A,B)}catch(q){G(`session "${$.sessionName}": kill status card close failed: ${F(q)}`),await C($.chatId,`${B}
170
- ⚠️ kill 状态卡片终态写入失败: ${F(q)}`)}}if(K&&!A)await C($.chatId,B)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let X=$.lastSessionId?V$($.lastSessionId):"",V=$.backendLabel($.proc?.provider??$.currentProvider()),z=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${V}`):X?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${X}`):$.withModel(`\uD83D\uDD01 启动 ${V}`),A=await $.openStatusCard("restart",z),K=z,B=await $.restart(!0,{announce:!A,onStatus:(L)=>{K=L,$.setStatusCard(A,L)}}),q=B?K.startsWith("✅")?K:$.withWorktreeInstructionNotice(X?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):K.startsWith("❌")?K:"❌ 重启失败";await $.closeStatusCard(A,B?$.withModel(q):q)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let X=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(X)await $.closeStatusCard(X,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await N($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let X=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),V="\uD83E\uDDF9 清空并启动新会话",z=await $.restart(!1,{announce:!X,onStatus:(A)=>{V=A,$.setStatusCard(X,A)}});await $.closeStatusCard(X,z?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):V.startsWith("❌")?V:"❌ 清空失败")}return!0}}var DK;var eY=S(()=>{o();g();DK=new Map([["hi","hi"],["stop","stop"],["st","stop"],["kill","kill"],["kl","kill"],["restart","restart"],["rs","restart"],["clear","clear"],["cl","clear"],["compact","compact"],["cm","compact"],["model","model"],["md","model"]])});function FK($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,W=()=>{$.off("context_compacted",V),$.off("exit",z),$.off("error",A)},H=(B)=>{if(Z)return;Z=!0,W(),J(B)},X=(B)=>{if(Z)return;Z=!0,W(),Y(B)},V=(B)=>{if(B.phase==="start")return;if(B.threadId&&Q&&B.threadId!==Q)return;H(B)},z=()=>X(Error(`${$.provider} process exited before context compaction completed`)),A=(B)=>X(B instanceof Error?B:Error(String(B))),K=new Promise((B,q)=>{J=B,Y=q});return $.on("context_compacted",V),$.once("exit",z),$.once("error",A),{promise:K,cancel(){if(Z)return;Z=!0,W()}}}function UK($,Z){let J=[],Y=new Set,Q=(X,V)=>{let z=V.threadId??Z;if(z&&X.threadId&&X.threadId!==z)return!1;if(V.turnId)return X.turnId===V.turnId;return!0},W=(X)=>{for(let V=J.length-1;V>=0;V--){let z=J[V];if(z&&Q(z,X))return z}return null},H=(X)=>{if(Z&&X.threadId&&X.threadId!==Z)return;let V={usage:X.usage,contextWindow:X.contextWindow,threadId:X.threadId,turnId:X.turnId};J.push(V);for(let z of[...Y])if(Q(V,z.notice))z.finish(V)};return $.on("token_usage",H),{waitFor(X,V){let z=W(X);if(z)return Promise.resolve(z);return new Promise((A)=>{let K=null,B={notice:X,finish:(q)=>{if(K)clearTimeout(K);Y.delete(B),A(q)}};K=setTimeout(()=>B.finish(null),V),Y.add(B)})},cancel(){$.off("token_usage",H);for(let X of[...Y])X.finish(null)}}}function OK($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=I4($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=c4($.contextWindow);return` · \uD83E\uDDE0 ${l3(Z,J)} (${m4(Z,J)})`}async function $Q($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let z=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(z)await $.closeStatusCard(z,"⚪ 后端未运行,compact 无效");else await N($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let z=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(z)await $.closeStatusCard(z,"⚠️ 先 stop 当前 turn,再 compact");else await N($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let z=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(z)await $.closeStatusCard(z,"⏳ 上下文压缩已在进行中");else await N($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?V$(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),W=await $.openStatusCard("compact",Q,"orange"),H=async(z)=>{if(W)await $.closeStatusCard(W,z);else await N($.chatId,z)},X=FK(J),V=UK(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(W,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(W,$.withModel("⏳ 等待压缩完成事件"));let z=await X.promise,A=await V.waitFor(z,MK),K=z.threadId?` thread=${V$(z.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${K}${OK(A)}`))}catch(z){if(X.cancel(),z instanceof Q2)await H($.withModel(`ⓘ ${z.message}`));else await H(`❌ 上下文压缩失败: ${F(z)}`)}finally{V.cancel(),$.manualContextCompactionPending=!1}}var MK=1500;var ZQ=S(()=>{v0();o()});import{randomUUID as TK}from"node:crypto";function NK($){let Z=$.currentTokenSource();return I0().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,selected:Z?.id===J.id}))}function JQ($,Z){let J=$.currentModelLabel(),Y=$.currentEffortLabel(),Q=$.currentTokenSource()?.id===Z.id;return Z.models.map((W)=>{let H=Q&&J===W.model;return{provider:Z.agent,sourceId:Z.id,model:W.model,displayName:W.display,description:Z.display,enabled:!0,isDefault:!1,selected:H,efforts:W.efforts.map((X)=>({effort:X,description:"",isDefault:X===W.defaultEffort,selected:H&&Y===X}))}})}async function YQ($){z2();let Z=TK(),J=NK($);if($.modelPanels.set(Z,{models:[]}),!await i($.chatId,G7({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J})))$.modelPanels.delete(Z),await C($.chatId,"❌ 模型面板发送失败")}async function QQ($,Z,J=""){let Y=Z.trim(),Q=e(Y);if(!Q)return{ok:!1,message:`未知账号: ${Y}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置,请先点「启用」`};let W=J.trim(),H=JQ($,Q);return $.modelPanels.set(W,{models:H}),{ok:!0,message:"",card:A7({sessionName:$.sessionName,panelId:W,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:H})}}async function WQ($,Z,J,Y=""){let Q=e(Z.trim());if(!Q)return{ok:!1,message:`未知账号: ${Z}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置`};if(Q.agent!=="claude"||!Q.verifyModel)return{ok:!1,message:`${Q.display} 不支持手动补录模型`};let W=J.trim();if(!W)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:W,cardMessageId:Y},{ok:!0,message:"等待模型名",card:_7($.sessionName,Q.display,W)}}async function HQ($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),W=e(Y.sourceId),H=async(L)=>{if(!Y.cardMessageId)return!1;let R="",D=!1,U=!1;try{if(R=await o$(Y.cardMessageId),u$(R,1),D=await D$(R,M.modelPanel,L,{notifyCardFailure:!1}),!D)throw Error("model panel replace rejected");if(U=await K$(R,{config:{streaming_mode:!1}}),!U)throw Error("model panel streaming-off rejected")}catch(P){G(`model-custom: card update MISS (${P?.message??P})`)}finally{if(R){if(!U)try{U=await K$(R,{config:{streaming_mode:!1}})}catch(P){G(`model-custom: streaming-off retry MISS (${P?.message??P})`)}if(D&&U)try{await C$(R)}catch(P){G(`model-custom: card dispose MISS (${P?.message??P})`)}else G(`model-custom: retain card state after checked MISS mutation=${D} streamingOff=${U} card=${R.slice(0,12)}`)}}return D&&U},X=async(L,R)=>{if(await H(L))return!0;let U=`⚠️ 模型补录结果未能写回原卡。${R}
171
- 请重新发送 model 打开面板。`;if(!await C($.chatId,U))G(`model-custom: visible fallback send MISS (${R})`);return!1},V=(L)=>X(z6(!1,Q,L),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${L}。`);if(!W||!W.enabled||!W.verifyModel)return await V("账号不可用"),!0;if(!Q)return await V("模型名为空"),!0;if(W.models.some((L)=>L.model.toLowerCase()===Q.toLowerCase()))return await X(z6(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;let z=await W.verifyModel(Q);if(z==="not_found")return await V("端点确认不存在"),!0;if(z==="no_verdict")return await V("无法校验(端点无响应或凭据问题)"),!0;let A=[...kK(W.id),Q].join(",");try{await T9(S6(W.id,{models:A}),15000,"refreshModels")}catch(L){return G(`model-custom: config/refresh MISS (${F(L)})`),await V(`配置写入或模型刷新失败:${F(L)}`),!0}G(`model-custom: ${W.id} 补录 ${Q} by ${J}(端点校验通过,已持久化)`);let K=e(W.id);if(!K||K.modelCatalogState?.status!=="ready")return await V(K?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let B=JQ($,K),q=B.find((L)=>L.model===Q);if(!q)return await V("模型已验证,但刷新后的模型列表未返回该项"),!0;return $.modelPanels.set(Y.panelId,{models:B}),await X(G6({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:q}),`✅ 模型 ${Q} 已补录成功。`),!0}function kK($){return(v.token_sources[$]?.models??"").split(",").map((J)=>J.trim()).filter(Boolean)}async function XQ($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:V6($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:V6($.sessionName)}}function SK($,Z){return Z?.provider==="claude"||Z?.provider==="codex"?Z.provider:j1($)}function yK($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${Z0(Z)} 时使用。`}async function VQ($,Z,J="",Y="",Q=null){let W=Z.trim();if(!W)return await N($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=SK(W,Q),X=$.modelPanels.get(J.trim())?.models.find((V)=>V.model===W&&(V.provider??"codex")===H);if(!X)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if(X.enabled===!1)return{ok:!1,message:`${X.displayName} 未配置,请先点「启用」`};if(X.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};return{ok:!0,message:"",card:K7({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function zQ($,Z,J,Y="",Q="",W=""){let H=Z.trim(),X=J.trim();if(!H)return{ok:!1,message:"模型为空"};let V=Y.trim(),z=$.modelPanels.get(V),A=W==="claude"||W==="codex"?W:z?.models.find((P)=>P.model===H)?.provider??j1(H);if(A==="claude"){if(!n$(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!k$(X))return{ok:!1,message:"Codex reasoning effort 无效"};let K=X,B=z?.models.find((P)=>P.model===H&&(P.provider??"codex")===A);if(!B||!B.efforts.some((P)=>P.effort===K))return{ok:!1,message:`${Z0(A)} · ${H}/${K} 不在选项中`};let q=!!B.sourceId&&$.currentTokenSource()?.id!==B.sourceId;if($.currentProvider()===A&&!q&&$.currentModelLabel()===H&&$.currentEffortLabel()===K)return $.modelPanels.delete(V),{ok:!0,message:`当前已是 ${Z0(A)} · ${H} / ${K}`,card:X6({sessionName:$.sessionName,provider:A,model:H,effort:K,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==A&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${Z0(A)}`};let D=$.currentModelLabel()!==H||q,U=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(A==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&D&&U)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===A&&!q){let j=B.sourceId?e(B.sourceId)?.resolveSpawnModel(H)??H:H;await T9($.proc.setModelSettings(j,K),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(A,H,K,B.sourceId);let P=yK($,A);return $.modelPanels.delete(V),{ok:!0,message:`已选择 ${Z0(A)} · ${H} / ${K}`,card:X6({sessionName:$.sessionName,provider:A,model:H,effort:K,scope:P})}}catch(P){let j=`模型切换失败: ${F(P)}`;return G(`session "${$.sessionName}": set model settings failed: ${F(P)}`),await N($.chatId,`❌ ${j}`),{ok:!1,message:j}}}var GQ=S(()=>{U$();G$();t7();P1();v0();f$();d0();o();g()});import{createHash as CK}from"node:crypto";function bK($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function J1(){return fK(I0())}function fK($){let Z=[],J=[];for(let Y of $)wK(Y,Z,J);return{catalogGeneration:CK("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function wK($,Z,J){let Y=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Y==="loading"||Y==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Y==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Q of $.models)Z.push(vK($,Q,Y))}function vK($,Z,J){let Y="ready",Q;if(!$.enabled)Y="source_disabled",Q="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Y="catalog_loading",Q="模型目录正在刷新";else if(J==="failed")Y="catalog_failed",Q=$.modelCatalogState?.error??"模型目录刷新失败";return{id:bK($.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:AQ($.defaultModel)===AQ(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function AQ($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var y6=S(()=>{G$()});import{randomUUID as hK}from"node:crypto";async function KQ($,Z){if(!Z.trim()){await C($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}qQ(),await O1();let J=`agents_${hK()}`;if(I2.set(J,{ownerOpenId:Z,page:0,createdAt:Date.now()}),!await i($.chatId,BQ(J)))await C($.chatId,"❌ agents 面板发送失败")}function _Q($,Z,J){let Y=cK($,J),Q=Number(Z);if(!Number.isInteger(Q))return mK("无效页码");let W=IK();return Y.page=Math.max(0,Math.min(W-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:BQ($)}}function BQ($){let Z=I2.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=J1(),Y=Math.max(1,Math.ceil(J.identities.length/x6));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*x6;return N7({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+x6),failures:J.sourceFailures})}function IK(){return Math.max(1,Math.ceil(J1().identities.length/x6))}function cK($,Z){qQ();let J=I2.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function mK($){return{ok:!1,message:$,card:O0({title:"agents",message:$,ok:!1})}}function qQ(){let $=Date.now()-gK;for(let[Z,J]of I2)if(J.createdAt<$)I2.delete(Z)}var x6=8,gK=1800000,I2;var RQ=S(()=>{f$();o();y6();G$();I2=new Map});var J5={};G1(J5,{withTasklistLifecycleLock:()=>w6,tasklistNameForProject:()=>f6,reconcileTasklistDeletions:()=>iK,isTasklistAlreadyDeletedError:()=>LQ,getTasklistBinding:()=>A0,enableTasklist:()=>$5,deleteTasklistRemoteIdempotently:()=>PQ,deleteTasklist:()=>Z5});import{existsSync as pK,readFileSync as lK}from"node:fs";function f6($){return`${$}[lodestar]`}function A0($){let Z=G0.get($);return Z?g1(Z):null}async function w6($,Z){let J=C6.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),W=J.catch(()=>{}).then(()=>Q);C6.set($,W),await J.catch(()=>{});try{return await Z()}finally{if(Y(),C6.get($)===W)C6.delete($)}}function LQ($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function PQ($,Z=V8){try{return await Z($),"deleted"}catch(J){if(LQ(J))return"already_deleted";throw J}}async function $5($,Z){return await w6($,async()=>{let J=A0($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=f6($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await H8(Z),W=await X8(Y,Q),H={guid:W.guid,name:W.name,url:W.url,projectName:$,ownerOpenId:Q,createdAt:W.createdAt};return b6($,H),g1(H)})}async function Z5($,Z){return await w6($,async()=>{let J=A0($);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},b6($,J);return await DQ($,Z)})}async function DQ($,Z){let J=A0($);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,b6($,J);try{if(await PQ(Z)==="already_deleted")G(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(G0);return Q.delete($),jQ(Q),G0.delete($),g1(J)}catch(Y){let Q=A0($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),b6($,Q);throw Y}}async function iK(){let $=[...G0.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await w6(J.projectName,()=>DQ(J.projectName,J.guid)),G(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Y){Z.push(`${J.projectName}: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function dK(){if(!pK(o2))return;try{let $=JSON.parse(lK(o2,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Y=J;if(typeof Y.guid!=="string"||!Y.guid||typeof Y.name!=="string"||!Y.name)continue;let Q={guid:Y.guid,name:Y.name,url:typeof Y.url==="string"?Y.url:"",projectName:Z,ownerOpenId:typeof Y.ownerOpenId==="string"?Y.ownerOpenId:"",createdAt:typeof Y.createdAt==="string"?Y.createdAt:void 0,deleting:nK(Y.deleting)};G0.set(Z,Q)}G(`tasklist: loaded ${G0.size} project bindings`)}catch($){G(`tasklist: load map failed: ${$}`)}}function nK($){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 b6($,Z){let J=new Map(G0);J.set($,g1(Z)),jQ(J),G0.set($,g1(Z))}function jQ($=G0){let Z={};for(let[J,Y]of $)Z[J]=g1(Y);H$(o2,Z)}function g1($){return JSON.parse(JSON.stringify($))}var G0,C6;var Y5=S(()=>{R$();o();g();g$();G0=new Map,C6=new Map;dK()});function N0($,Z,J=!1){let Y=$.worktreeProjectName();return O7({projectName:Y,tasklistName:f6(Y),binding:A0(Y),notice:Z,confirmDelete:J})}async function MQ($){if(!await i($.chatId,N0($)))await C($.chatId,"❌ task 面板发送失败")}async function FQ($){let Z=$.worktreeProjectName();try{let J=A0(Z),Y=await $5(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:N0($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${F(J)}`;return G(`session "${$.sessionName}": tasklist enable failed: ${F(J)}`),{ok:!1,message:Y,card:N0($,{type:"error",content:`❌ ${Y}`})}}}function UQ($,Z){let J=$.worktreeProjectName(),Y=A0(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:N0($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:N0($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:N0($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function OQ($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let W=`已删除 ${(await Z5(J,Y)).name}`;return{ok:!0,message:W,card:N0($,{type:"success",content:`✅ ${W}`})}}catch(Q){let W=`删除失败: ${F(Q)}`;return G(`session "${$.sessionName}": tasklist delete failed: ${F(Q)}`),{ok:!1,message:W,card:N0($,{type:"error",content:`❌ ${W}`})}}}var EQ=S(()=>{f$();o();g();Y5()});var TQ,NQ,kQ,SQ;var yQ=S(()=>{TQ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。"],NQ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会根据工具返回的本机图片路径自动发给用户。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],kQ=[...TQ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...NQ].join(`
172
- `),SQ=[...TQ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...NQ].join(`
173
- `)});import{execFileSync as oK}from"node:child_process";import{existsSync as Y1,readdirSync as rK,readFileSync as tK,realpathSync as Q5,statSync as sK}from"node:fs";import{dirname as eK,join as CQ,resolve as h6}from"node:path";async function g6($,Z){let J=Q5($),Y=process.platform==="win32"?J.toLowerCase():J,Q=v6.get(Y)??Promise.resolve(),W,H=new Promise((V)=>{W=V}),X=Q.catch(()=>{}).then(()=>H);v6.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(W(),v6.get(Y)===X)v6.delete(Y)}}function Q1($){let Z=$.trim();if(!$_.test(Z))return null;return Z}function bQ($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function c1($,Z){return`${$}[${Z}]`}function fQ($){return`${I1}${$}`}function m1($,Z,J){return CQ(eK($),c1(Z,J))}function wQ($,Z,J){let Y=Z_($,Z,J);if(!Y)return null;let Q=tK(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function vQ($,Z){H5($);let J=B$($,["for-each-ref","--format=%(refname:short)",`refs/heads/${I1}`]).split(`
174
- `).map((W)=>W.trim()).filter(Boolean).filter((W)=>W.startsWith(I1)),Y=X5($),Q=[];for(let W of J){let H=W.slice(I1.length);if(!Q1(H))continue;let X=c1(Z,H),V=m1($,Z,H),z=Y.get(W)??null,A=!!z&&Y1(z),K=cQ($,W,A),B={slug:H,chatName:X,branch:W,state:K,expectedPath:V,worktreePath:A?z:null,mounted:A,dirtyCount:null,statusLine:null,error:null};if(z&&Y1(z))try{let L=B$(z,["status","--porcelain=v1","--branch"]).split(`
175
- `).filter(Boolean);B.statusLine=L[0]?.startsWith("## ")?L[0].slice(3):null,B.dirtyCount=L.filter((R)=>!R.startsWith("## ")).length}catch(q){B.error=V5(q)}Q.push(B)}return Q.sort((W,H)=>W.slug.localeCompare(H.slug))}function hQ($,Z,J){let Y=Q1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);H5($);let Q=fQ(Y),W=c1(Z,Y),H=m1($,Z,Y),X=W_($,Q),V=X5($).get(Q)??null,z=X&&!V&&cQ($,Q,!1)==="merged"?B$($,["rev-parse","HEAD"]).trim():null;if(V){if(h6(V)!==h6(H))throw Error(`branch ${Q} is already mounted at ${V}`);return IQ(H,Q),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(Y1(H)){if(!sK(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!X)throw Error(`${H} already exists while branch ${Q} does not`)}if(X){if(B$($,["worktree","add",H,Q]),z)B$(H,["rebase",z]);return{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return B$($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function gQ($,Z,J){let Y=W5($,Z,J);if(!Y1(Y.worktreePath))return Y;return B$($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function W5($,Z,J){let Y=Q1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);H5($);let Q=fQ(Y),W=c1(Z,Y),H=m1($,Z,Y),V=X5($).get(Q)??null??H;if(!Y1(V))return{slug:Y,chatName:W,branch:Q,worktreePath:V,removedWorktree:!1};IQ(V,Q);let z=B$(V,["status","--porcelain=v1"]).split(`
176
- `).filter(Boolean);if(z.length>0){let A=z.slice(0,8).join(`
168
+ `+f_($,G)+`
169
+ `),UZ(),B5(),await P2()}var L5=N(()=>{L0();U0();q5();G0();I0()});var P5={};B1(P5,{runTokenSourceSetup:()=>h_,onTokenSourceEnable:()=>v_});async function v_($,Z){let J=$0(Z);if(!J){await T($.chatId,`❌ 未知 token source: ${Z}`);return}if(J.enabled){await T($.chatId,`${J.display} 已启用,发 \`model\` 选择。`);return}let Y=N1().find((Q)=>Q.setup?.commandSuffix===Z||Q.configSectionId===Z);if(Y?.setup)await T($.chatId,Y.setup.hint(J.display));else if(J.kind==="codex-subscription")await T($.chatId,`${J.display} 需要 ChatGPT 登录:在服务器执行 \`codex login\`,完成后按当前服务管理方式重启 daemon,或重发 \`model\` 刷新。`);else if(J.kind==="claude-native")await T($.chatId,`${J.display} 直接使用本机 Claude Code 配置,无需单独启用。`)}async function h_($,Z,J){let Y=N1().find((W)=>W.setup?.commandSuffix===Z);if(!Y?.setup||!Y.configSectionId){await T($.chatId,`❌ 未知或不可配置的 source: ${Z}`);return}let Q=Y.setup.parseArgs(J);if("error"in Q){await T($.chatId,Q.error);return}try{await l9(Y.configSectionId,Q.config);let W=$0(Y.configSectionId);await T($.chatId,`✅ ${W?.display??Z} 已启用。发 \`model\` 重新选择。`)}catch(W){await T($.chatId,`❌ 启用失败: ${W?.message??W}`)}}var j5=N(()=>{s();G0();L5()});async function MQ($,Z,J=""){let Y=Z.trim().match(/^(?:wt|worktree)(?:\s+(.+))?$/i);if(Y)return await $.runWorktreeCommand((Y[1]??"").trim(),J),!0;if(Z.trim().match(/^btw$/i))return await $.runBtwCommand(J),!0;if(Z.trim().match(/^bye$/i))return await $.runByeCommand(),!0;if(Z.trim().match(/^(?:fk|fork)$/i))return await $.showForkList(J),!0;if(Z.trim().match(/^(?:bk|back)$/i))return await $.showBackList(J),!0;if(Z.trim().toLowerCase()==="task")return await $.showTasklistPanel(),!0;if(Z.trim().match(/^(?:agents|agent)$/i))return await $.showAgentIdentityPanel(J),!0;let Q=Z.trim().match(/^(\w+)-setup\s+([\s\S]+)$/i);if(Q){let{runTokenSourceSetup:H}=await Promise.resolve().then(() => (j5(),P5));return await H($,Q[1].trim(),Q[2].trim()),!0}let W=g_.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 X=!$.isRunning(),V=$.backendLabel(),z=X?await $.openStatusCard("hi",$.withModel(`\uD83D\uDE80 启动 ${V}`)):null,G=$.withModel(`\uD83D\uDE80 启动 ${V}`);if(!(X?await $.start({announce:!z,onStatus:(B)=>{G=B,$.setStatusCard(z,B)}}):!0))return await $.closeStatusCard(z,G.startsWith("❌")?G:"❌ 启动失败"),!0;if(z)return await $.replaceStatusCardWithConsole(z,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`))),!0;if(X)await $.closeStatusCard(z,$.withModel($.withWorktreeInstructionNotice(`✅ ${$.backendLabel()} 已就绪`)))}return await $.showConsole(),!0;case"stop":if(await $.cancelAgentRuns("stop command"),$.clearStaleIdleQueueState("stop"),$.clearMultiMsgBuffer("stop command"),!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0){let X=await $.openStatusCard("stop","⚪ 当前没有正在执行的 turn","grey");if(X)await $.closeStatusCard(X,"⚪ 无正在执行的 turn");else await T($.chatId,"⚪ 当前没有正在执行的 turn");return!0}A(`session "${$.sessionName}": stop command — interrupt + drop count=${$.pendingUserMessageCount} midBuffer=${$.pendingMidTurnMsgs.length}`);let H=new Set;for(let[X,V]of[...$.pendingReactionIds.entries(),...$.currentBatchReactionIds.entries()]){if(V)j0(X,V);T0(X,"CrossMark"),H.add(X)}for(let X of $.pendingMidTurnMsgs)if(X.msgId&&!H.has(X.msgId))T0(X.msgId,"CrossMark");return $.pendingUserMessageCount=0,$.pendingMidTurnMsgs=[],$.pendingTurnInputs=[],$.lastUserOpenId="",$.pendingReactionIds=new Map,$.currentBatchReactionIds=new Map,$.userInterrupted=!0,$.interrupt(),await $.closeTurnCard("\uD83D\uDED1 打断"),!0;case"kill":{let X=$.isRunning(),V=$.backendLabel($.proc?.provider??$.currentProvider()),z=X?`\uD83D\uDED1 停止 ${V}`:"⚪ session 当前未运行",G=await $.openStatusCard("kill",z,X?"red":"grey"),_=null,B=X?`✅ ${V} 已终止`:`⚪ ${V} 未运行`;try{await $.stop("已终止",{announce:!G,onStatus:(q)=>{$.setStatusCard(G,q)}})}catch(q){_=q,B=$.isRunning()?`❌ ${V} 未确认终止: ${F(q)};会话已阻断,请重试 kill/restart 或等待旧进程退出`:`❌ ${V} 停止收尾失败: ${F(q)}`}finally{try{await $.closeStatusCard(G,B)}catch(q){A(`session "${$.sessionName}": kill status card close failed: ${F(q)}`),await C($.chatId,`${B}
170
+ ⚠️ kill 状态卡片终态写入失败: ${F(q)}`)}}if(_&&!G)await C($.chatId,B)}return!0;case"restart":if(!$.isRunning())return await $.showResumeList(J),!0;{let X=$.lastSessionId?V0($.lastSessionId):"",V=$.backendLabel($.proc?.provider??$.currentProvider()),z=$.isRunning()?$.withModel(`\uD83D\uDD01 重启 ${V}`):X?$.withModel(`\uD83D\uDD01 恢复上一会话 thread=${X}`):$.withModel(`\uD83D\uDD01 启动 ${V}`),G=await $.openStatusCard("restart",z),_=z,B=await $.restart(!0,{announce:!G,onStatus:(L)=>{_=L,$.setStatusCard(G,L)}}),q=B?_.startsWith("✅")?_:$.withWorktreeInstructionNotice(X?"✅ 已恢复上一会话":`✅ ${$.backendLabel()} 已就绪`):_.startsWith("❌")?_:"❌ 重启失败";await $.closeStatusCard(G,B?$.withModel(q):q)}return!0;case"clear":if(!$.isRunning()){$.status="stopped",$.opts.onLifecycleChange?.();let X=await $.openStatusCard("clear","⚪ session 当前未运行","grey");if(X)await $.closeStatusCard(X,`⚪ ${$.backendLabel()} 未运行,clear 无效`);else await T($.chatId,`⚪ session "${$.sessionName}" 当前未运行,clear 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return!0}{let X=await $.openStatusCard("clear","\uD83E\uDDF9 清空并启动新会话","orange"),V="\uD83E\uDDF9 清空并启动新会话",z=await $.restart(!1,{announce:!X,onStatus:(G)=>{V=G,$.setStatusCard(X,G)}});await $.closeStatusCard(X,z?$.withModel($.withWorktreeInstructionNotice("✅ 已清空并启动新会话")):V.startsWith("❌")?V:"❌ 清空失败")}return!0}}var g_;var FQ=N(()=>{s();I();g_=new Map([["hi","hi"],["stop","stop"],["st","stop"],["kill","kill"],["kl","kill"],["restart","restart"],["rs","restart"],["clear","clear"],["cl","clear"],["compact","compact"],["cm","compact"],["model","model"],["md","model"]])});function m_($){let Z=!1,J=()=>{},Y=()=>{},Q=$.sessionId,W=()=>{$.off("context_compacted",V),$.off("exit",z),$.off("error",G)},H=(B)=>{if(Z)return;Z=!0,W(),J(B)},X=(B)=>{if(Z)return;Z=!0,W(),Y(B)},V=(B)=>{if(B.phase==="start")return;if(B.threadId&&Q&&B.threadId!==Q)return;H(B)},z=()=>X(Error(`${$.provider} process exited before context compaction completed`)),G=(B)=>X(B instanceof Error?B:Error(String(B))),_=new Promise((B,q)=>{J=B,Y=q});return $.on("context_compacted",V),$.once("exit",z),$.once("error",G),{promise:_,cancel(){if(Z)return;Z=!0,W()}}}function u_($,Z){let J=[],Y=new Set,Q=(X,V)=>{let z=V.threadId??Z;if(z&&X.threadId&&X.threadId!==z)return!1;if(V.turnId)return X.turnId===V.turnId;return!0},W=(X)=>{for(let V=J.length-1;V>=0;V--){let z=J[V];if(z&&Q(z,X))return z}return null},H=(X)=>{if(Z&&X.threadId&&X.threadId!==Z)return;let V={usage:X.usage,contextWindow:X.contextWindow,threadId:X.threadId,turnId:X.turnId};J.push(V);for(let z of[...Y])if(Q(V,z.notice))z.finish(V)};return $.on("token_usage",H),{waitFor(X,V){let z=W(X);if(z)return Promise.resolve(z);return new Promise((G)=>{let _=null,B={notice:X,finish:(q)=>{if(_)clearTimeout(_);Y.delete(B),G(q)}};_=setTimeout(()=>B.finish(null),V),Y.add(B)})},cancel(){$.off("token_usage",H);for(let X of[...Y])X.finish(null)}}}function p_($){if(!$)return" · \uD83E\uDDE0 MISS";let Z=o4($.usage);if(Z==null)return" · \uD83E\uDDE0 MISS";let J=r4($.contextWindow);return` · \uD83E\uDDE0 ${HJ(Z,J)} (${t4(Z,J)})`}async function UQ($){$.clearStaleIdleQueueState("compact");let Z=!$.currentTurn&&$.pendingUserMessageCount===0&&$.pendingMidTurnMsgs.length===0&&!$.openingTurn;if(!$.isRunning()||!$.proc){$.status="stopped",$.opts.onLifecycleChange?.();let z=await $.openStatusCard("compact","⚪ session 当前未运行","grey");if(z)await $.closeStatusCard(z,"⚪ 后端未运行,compact 无效");else await T($.chatId,`⚪ session "${$.sessionName}" 当前未运行,compact 无效;用 \`hi\` 启动或 \`restart\` 恢复上一会话`);return}if(!Z){let z=await $.openStatusCard("compact","⚠️ 当前 turn 正在执行","grey");if(z)await $.closeStatusCard(z,"⚠️ 先 stop 当前 turn,再 compact");else await T($.chatId,"⚠️ 当前 turn 正在执行,先 `stop` 后再 `compact`。");return}if($.manualContextCompactionPending){let z=await $.openStatusCard("compact","⏳ 上下文压缩已在进行中","grey");if(z)await $.closeStatusCard(z,"⏳ 上下文压缩已在进行中");else await T($.chatId,"⏳ 上下文压缩已在进行中。");return}let J=$.proc,Y=J.sessionId?V0(J.sessionId):"",Q=$.withModel(Y?`\uD83E\uDDE0 压缩上下文 thread=${Y}`:"\uD83E\uDDE0 压缩上下文…"),W=await $.openStatusCard("compact",Q,"orange"),H=async(z)=>{if(W)await $.closeStatusCard(W,z);else await T($.chatId,z)},X=m_(J),V=u_(J,J.sessionId);$.manualContextCompactionPending=!0;try{$.setStatusCard(W,$.withModel("\uD83E\uDDE0 发起上下文压缩")),await J.compactThread(),$.setStatusCard(W,$.withModel("⏳ 等待压缩完成事件"));let z=await X.promise,G=await V.waitFor(z,c_),_=z.threadId?` thread=${V0(z.threadId)}`:"";await H($.withModel(`✅ 上下文已压缩${_}${p_(G)}`))}catch(z){if(X.cancel(),z instanceof _2)await H($.withModel(`ⓘ ${z.message}`));else await H(`❌ 上下文压缩失败: ${F(z)}`)}finally{V.cancel(),$.manualContextCompactionPending=!1}}var c_=1500;var OQ=N(()=>{I$();s()});import{randomUUID as i_}from"node:crypto";function d_($){let Z=$.currentTokenSource();return u$().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,selected:Z?.id===J.id}))}function EQ($,Z){let J=$.currentModelLabel(),Y=$.currentEffortLabel(),Q=$.currentTokenSource()?.id===Z.id;return Z.models.map((W)=>{let H=Q&&J===W.model;return{provider:Z.agent,sourceId:Z.id,model:W.model,displayName:W.display,description:Z.display,enabled:!0,isDefault:!1,selected:H,efforts:W.efforts.map((X)=>({effort:X,description:"",isDefault:X===W.defaultEffort,selected:H&&Y===X}))}})}async function TQ($){P2();let Z=i_(),J=d_($);if($.modelPanels.set(Z,{models:[]}),!await i($.chatId,O8({sessionName:$.sessionName,panelId:Z,currentDisplay:$.currentTokenSource()?.display??$.currentModelLabel(),providers:J})))$.modelPanels.delete(Z),await C($.chatId,"❌ 模型面板发送失败")}async function NQ($,Z,J=""){let Y=Z.trim(),Q=$0(Y);if(!Q)return{ok:!1,message:`未知账号: ${Y}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置,请先点「启用」`};let W=J.trim(),H=EQ($,Q);return $.modelPanels.set(W,{models:H}),{ok:!0,message:"",card:E8({sessionName:$.sessionName,panelId:W,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),models:H})}}async function kQ($,Z,J,Y=""){let Q=$0(Z.trim());if(!Q)return{ok:!1,message:`未知账号: ${Z}`};if(!Q.enabled)return{ok:!1,message:`${Q.display} 未配置`};if(Q.agent!=="claude"||!Q.verifyModel)return{ok:!1,message:`${Q.display} 不支持手动补录模型`};let W=J.trim();if(!W)return{ok:!1,message:"补录面板缺少 panel_id,请重新发送 model"};return $.modelCustomPrompt={sourceId:Q.id,panelId:W,cardMessageId:Y},{ok:!0,message:"等待模型名",card:N8($.sessionName,Q.display,W)}}async function SQ($,Z,J){let Y=$.modelCustomPrompt;if(!Y)return!1;$.modelCustomPrompt=null;let Q=Z.trim(),W=$0(Y.sourceId),H=async(L)=>{if(!Y.cardMessageId)return!1;let P="",R=!1,O=!1;try{if(P=await t0(Y.cardMessageId),p0(P,1),R=await R0(P,M.modelPanel,L,{notifyCardFailure:!1}),!R)throw Error("model panel replace rejected");if(O=await _0(P,{config:{streaming_mode:!1}}),!O)throw Error("model panel streaming-off rejected")}catch(j){A(`model-custom: card update MISS (${j?.message??j})`)}finally{if(P){if(!O)try{O=await _0(P,{config:{streaming_mode:!1}})}catch(j){A(`model-custom: streaming-off retry MISS (${j?.message??j})`)}if(R&&O)try{await C0(P)}catch(j){A(`model-custom: card dispose MISS (${j?.message??j})`)}else A(`model-custom: retain card state after checked MISS mutation=${R} streamingOff=${O} card=${P.slice(0,12)}`)}}return R&&O},X=async(L,P)=>{if(await H(L))return!0;let O=`⚠️ 模型补录结果未能写回原卡。${P}
171
+ 请重新发送 model 打开面板。`;if(!await C($.chatId,O))A(`model-custom: visible fallback send MISS (${P})`);return!1},V=(L)=>X(R9(!1,Q,L),`❌ ${Q?`模型 ${Q}`:"模型名"} 未加入:${L}。`);if(!W||!W.enabled||!W.verifyModel)return await V("账号不可用"),!0;if(!Q)return await V("模型名为空"),!0;if(W.models.some((L)=>L.model.toLowerCase()===Q.toLowerCase()))return await X(R9(!1,Q,"已在列表中"),`ℹ️ 模型 ${Q} 已在列表中,未重复加入。`),!0;let z=await W.verifyModel(Q);if(z==="not_found")return await V("端点确认不存在"),!0;if(z==="no_verdict")return await V("无法校验(端点无响应或凭据问题)"),!0;let G=[...n_(W.id),Q].join(",");try{await c6(l9(W.id,{models:G}),15000,"refreshModels")}catch(L){return A(`model-custom: config/refresh MISS (${F(L)})`),await V(`配置写入或模型刷新失败:${F(L)}`),!0}A(`model-custom: ${W.id} 补录 ${Q} by ${J}(端点校验通过,已持久化)`);let _=$0(W.id);if(!_||_.modelCatalogState?.status!=="ready")return await V(_?.modelCatalogState?.error??"刷新后的账号目录不可用"),!0;let B=EQ($,_),q=B.find((L)=>L.model===Q);if(!q)return await V("模型已验证,但刷新后的模型列表未返回该项"),!0;return $.modelPanels.set(Y.panelId,{models:B}),await X(D9({sessionName:$.sessionName,panelId:Y.panelId,currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:q}),`✅ 模型 ${Q} 已补录成功。`),!0}function n_($){return(v.token_sources[$]?.models??"").split(",").map((J)=>J.trim()).filter(Boolean)}async function yQ($,Z=""){let J=Z.trim(),Y=$.modelCustomPrompt;if(!J||!Y||Y.panelId!==J)return{ok:!1,message:"此补录面板已失效",card:j9($.sessionName,"stale")};return $.modelCustomPrompt=null,{ok:!0,message:"已取消",card:j9($.sessionName)}}function a_($,Z){return Z?.provider==="claude"||Z?.provider==="codex"?Z.provider:O1($)}function o_($,Z){if($.currentTurn)return"当前 turn 不变,后续新 turn 使用。";if($.proc?.isAlive()&&$.proc.provider===Z)return Z==="codex"?"Codex 需重启进程生效(发 restart)。":"下一轮开始使用。";return`下次启动 ${J$(Z)} 时使用。`}async function xQ($,Z,J="",Y="",Q=null){let W=Z.trim();if(!W)return await T($.chatId,`❌ ${"模型为空"}`),{ok:!1,message:"模型为空"};let H=a_(W,Q),X=$.modelPanels.get(J.trim())?.models.find((V)=>V.model===W&&(V.provider??"codex")===H);if(!X)return{ok:!1,message:"模型不在当前选项中,请重新发送 model"};if(X.enabled===!1)return{ok:!1,message:`${X.displayName} 未配置,请先点「启用」`};if(X.efforts.length===0)return{ok:!1,message:"模型未返回 effort"};return{ok:!0,message:"",card:T8({sessionName:$.sessionName,panelId:J.trim(),currentModel:$.currentModelLabel(),currentEffort:$.currentEffortLabel(),model:X})}}async function bQ($,Z,J,Y="",Q="",W=""){let H=Z.trim(),X=J.trim();if(!H)return{ok:!1,message:"模型为空"};let V=Y.trim(),z=$.modelPanels.get(V),G=W==="claude"||W==="codex"?W:z?.models.find((j)=>j.model===H)?.provider??O1(H);if(G==="claude"){if(!a0(X))return{ok:!1,message:"Claude reasoning effort 无效"}}else if(!S0(X))return{ok:!1,message:"Codex reasoning effort 无效"};let _=X,B=z?.models.find((j)=>j.model===H&&(j.provider??"codex")===G);if(!B||!B.efforts.some((j)=>j.effort===_))return{ok:!1,message:`${J$(G)} · ${H}/${_} 不在选项中`};let q=!!B.sourceId&&$.currentTokenSource()?.id!==B.sourceId;if($.currentProvider()===G&&!q&&$.currentModelLabel()===H&&$.currentEffortLabel()===_)return $.modelPanels.delete(V),{ok:!0,message:`当前已是 ${J$(G)} · ${H} / ${_}`,card:P9({sessionName:$.sessionName,provider:G,model:H,effort:_,scope:"当前已是此设置,无需变更。"})};if($.proc?.isAlive()&&$.proc.provider!==G&&($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0))return{ok:!1,message:`当前 ${$.backendLabel($.proc.provider)} turn 正在执行或排队;请等结束或 stop 后再切换到 ${J$(G)}`};let R=$.currentModelLabel()!==H||q,O=!!($.currentTurn||$.openingTurn||$.pendingUserMessageCount>0||$.pendingMidTurnMsgs.length>0);if(G==="claude"&&$.proc?.isAlive()&&$.proc.provider==="claude"&&R&&O)return{ok:!1,message:"当前 Claude turn 正在执行或排队;Claude 模型 profile 通过 env 生效,请等结束或 stop 后再切换"};try{if($.proc?.isAlive()&&$.proc.provider===G&&!q){let D=B.sourceId?$0(B.sourceId)?.resolveSpawnModel(H)??H:H;await c6($.proc.setModelSettings(D,_),20000,"thread/settings/update")}await $.applyModelSelectionUnlocked(G,H,_,B.sourceId);let j=o_($,G);return $.modelPanels.delete(V),{ok:!0,message:`已选择 ${J$(G)} · ${H} / ${_}`,card:P9({sessionName:$.sessionName,provider:G,model:H,effort:_,scope:j})}}catch(j){let D=`模型切换失败: ${F(j)}`;return A(`session "${$.sessionName}": set model settings failed: ${F(j)}`),await T($.chatId,`❌ ${D}`),{ok:!1,message:D}}}var CQ=N(()=>{U0();G0();L5();F1();I$();f0();o$();s();I()});import{createHash as t_}from"node:crypto";function s_($,Z){return`agent:${Buffer.from(`${$}\x00${Z}`,"utf8").toString("base64url")}`}function W1(){return e_(u$())}function e_($){let Z=[],J=[];for(let Y of $)$K(Y,Z,J);return{catalogGeneration:t_("sha256").update(JSON.stringify({identities:Z,sourceFailures:J})).digest("hex").slice(0,16),identities:Z,sourceFailures:J}}function $K($,Z,J){let Y=$.modelCatalogState?.status??(!$.enabled?"disabled":$.models.length>0?"ready":"idle");if(!$.enabled)J.push({tokenSourceId:$.id,display:$.display,status:"disabled",reason:"账号未启用"});else if(Y==="loading"||Y==="idle")J.push({tokenSourceId:$.id,display:$.display,status:"loading",reason:"模型目录正在刷新"});else if(Y==="failed")J.push({tokenSourceId:$.id,display:$.display,status:"failed",reason:$.modelCatalogState?.error??"模型目录刷新失败"});else if($.models.length===0)J.push({tokenSourceId:$.id,display:$.display,status:"models_miss",reason:"模型目录为空"});for(let Q of $.models)Z.push(ZK($,Q,Y))}function ZK($,Z,J){let Y="ready",Q;if(!$.enabled)Y="source_disabled",Q="所属 Token Source 未启用";else if(J==="loading"||J==="idle")Y="catalog_loading",Q="模型目录正在刷新";else if(J==="failed")Y="catalog_failed",Q=$.modelCatalogState?.error??"模型目录刷新失败";return{id:s_($.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:wQ($.defaultModel)===wQ(Z.model),status:Y,...Q?{reason:Q}:{},spawnRevision:$.spawnRevision}}function wQ($){return $.replace(/\[1m\]$/i,"").toLowerCase()}var i9=N(()=>{G0()});import{randomUUID as JK}from"node:crypto";async function fQ($,Z){if(!Z.trim()){await C($.chatId,"❌ 无法确认操作者身份,未打开 agents 面板");return}gQ(),await k1();let J=`agents_${JK()}`;if(r2.set(J,{ownerOpenId:Z,page:0,createdAt:Date.now()}),!await i($.chatId,hQ(J)))await C($.chatId,"❌ agents 面板发送失败")}function vQ($,Z,J){let Y=WK($,J),Q=Number(Z);if(!Number.isInteger(Q))return HK("无效页码");let W=QK();return Y.page=Math.max(0,Math.min(W-1,Q)),Y.createdAt=Date.now(),{ok:!0,message:"已更新",card:hQ($)}}function hQ($){let Z=r2.get($);if(!Z)throw Error("Agent 身份面板已过期");let J=W1(),Y=Math.max(1,Math.ceil(J.identities.length/d9));Z.page=Math.min(Z.page,Y-1);let Q=Z.page*d9;return m8({panelId:$,page:Z.page,totalPages:Y,catalog:J.identities.slice(Q,Q+d9),failures:J.sourceFailures})}function QK(){return Math.max(1,Math.ceil(W1().identities.length/d9))}function WK($,Z){gQ();let J=r2.get($);if(!J)throw Error("Agent 身份面板已过期,请重新发送 agents");if(!J.ownerOpenId||!Z||J.ownerOpenId!==Z)throw Error("只有打开该面板的用户可操作");return J}function HK($){return{ok:!1,message:$,card:T$({title:"agents",message:$,ok:!1})}}function gQ(){let $=Date.now()-YK;for(let[Z,J]of r2)if(J.createdAt<$)r2.delete(Z)}var d9=8,YK=1800000,r2;var IQ=N(()=>{f0();s();i9();G0();r2=new Map});var M5={};B1(M5,{withTasklistLifecycleLock:()=>r9,tasklistNameForProject:()=>o9,reconcileTasklistDeletions:()=>GK,isTasklistAlreadyDeletedError:()=>cQ,getTasklistBinding:()=>_$,enableTasklist:()=>R5,deleteTasklistRemoteIdempotently:()=>mQ,deleteTasklist:()=>D5});import{existsSync as VK,readFileSync as zK}from"node:fs";function o9($){return`${$}[lodestar]`}function _$($){let Z=A$.get($);return Z?d1(Z):null}async function r9($,Z){let J=n9.get($)??Promise.resolve(),Y,Q=new Promise((H)=>{Y=H}),W=J.catch(()=>{}).then(()=>Q);n9.set($,W),await J.catch(()=>{});try{return await Z()}finally{if(Y(),n9.get($)===W)n9.delete($)}}function cQ($){if($&&typeof $==="object"&&$.code===1470404)return!0;let Z=$ instanceof Error?$.message:String($);return/\bcode=1470404\b/.test(Z)}async function mQ($,Z=F7){try{return await Z($),"deleted"}catch(J){if(cQ(J))return"already_deleted";throw J}}async function R5($,Z){return await r9($,async()=>{let J=_$($);if(J?.deleting)throw Error(`tasklist deletion is pending for ${$}`);if(J)return J;let Y=o9($);if(Y.length>100)throw Error(`tasklist name is too long (${Y.length}/100): ${Y}`);let Q=await D7(Z),W=await M7(Y,Q),H={guid:W.guid,name:W.name,url:W.url,projectName:$,ownerOpenId:Q,createdAt:W.createdAt};return a9($,H),d1(H)})}async function D5($,Z){return await r9($,async()=>{let J=_$($);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},a9($,J);return await uQ($,Z)})}async function uQ($,Z){let J=_$($);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,a9($,J);try{if(await mQ(Z)==="already_deleted")A(`tasklist: ${$} remote list ${Z} already deleted; finishing tombstone`);let Q=new Map(A$);return Q.delete($),pQ(Q),A$.delete($),d1(J)}catch(Y){let Q=_$($);if(Q?.guid===Z&&Q.deleting)Q.deleting.lastError=Y instanceof Error?Y.message:String(Y),a9($,Q);throw Y}}async function GK(){let $=[...A$.entries()].filter(([,J])=>!!J.deleting).map(([J,Y])=>({projectName:J,guid:Y.guid})),Z=[];for(let J of $)try{await r9(J.projectName,()=>uQ(J.projectName,J.guid)),A(`tasklist: reconciled pending deletion for ${J.projectName}`)}catch(Y){Z.push(`${J.projectName}: ${Y instanceof Error?Y.message:String(Y)}`)}if(Z.length)throw Error(`tasklist deletion reconcile failed: ${Z.join("; ")}`)}function AK(){if(!VK(Q4))return;try{let $=JSON.parse(zK(Q4,"utf8"));if(!$||typeof $!=="object")return;for(let[Z,J]of Object.entries($)){if(!J||typeof J!=="object")continue;let Y=J;if(typeof Y.guid!=="string"||!Y.guid||typeof Y.name!=="string"||!Y.name)continue;let Q={guid:Y.guid,name:Y.name,url:typeof Y.url==="string"?Y.url:"",projectName:Z,ownerOpenId:typeof Y.ownerOpenId==="string"?Y.ownerOpenId:"",createdAt:typeof Y.createdAt==="string"?Y.createdAt:void 0,deleting:_K(Y.deleting)};A$.set(Z,Q)}A(`tasklist: loaded ${A$.size} project bindings`)}catch($){A(`tasklist: load map failed: ${$}`)}}function _K($){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 a9($,Z){let J=new Map(A$);J.set($,d1(Z)),pQ(J),A$.set($,d1(Z))}function pQ($=A$){let Z={};for(let[J,Y]of $)Z[J]=d1(Y);H0(Q4,Z)}function d1($){return JSON.parse(JSON.stringify($))}var A$,n9;var F5=N(()=>{L0();s();I();I0();A$=new Map,n9=new Map;AK()});function S$($,Z,J=!1){let Y=$.worktreeProjectName();return g8({projectName:Y,tasklistName:o9(Y),binding:_$(Y),notice:Z,confirmDelete:J})}async function lQ($){if(!await i($.chatId,S$($)))await C($.chatId,"❌ task 面板发送失败")}async function iQ($){let Z=$.worktreeProjectName();try{let J=_$(Z),Y=await R5(Z,$.chatId),Q=J?"已启用":`已启用 ${Y.name}`;return{ok:!0,message:Q,card:S$($,{type:"success",content:`✅ ${Q}`})}}catch(J){let Y=`启用失败: ${F(J)}`;return A(`session "${$.sessionName}": tasklist enable failed: ${F(J)}`),{ok:!1,message:Y,card:S$($,{type:"error",content:`❌ ${Y}`})}}}function dQ($,Z){let J=$.worktreeProjectName(),Y=_$(J),Q=Z.trim();if(!Y)return{ok:!1,message:"未启用",card:S$($,{type:"error",content:"❌ 未启用"})};if(Y.guid!==Q)return{ok:!1,message:"清单绑定已变化",card:S$($,{type:"error",content:"❌ 清单绑定已变化,请重新打开 task 面板"})};return{ok:!0,message:"请再次确认删除",card:S$($,{type:"error",content:"⚠️ 删除会删除所有清单内任务"},!0)}}async function nQ($,Z){let J=$.worktreeProjectName(),Y=Z.trim();try{let W=`已删除 ${(await D5(J,Y)).name}`;return{ok:!0,message:W,card:S$($,{type:"success",content:`✅ ${W}`})}}catch(Q){let W=`删除失败: ${F(Q)}`;return A(`session "${$.sessionName}": tasklist delete failed: ${F(Q)}`),{ok:!1,message:W,card:S$($,{type:"error",content:`❌ ${W}`})}}}var aQ=N(()=>{f0();s();I();F5()});var oQ,rQ,tQ,sQ;var eQ=N(()=>{oQ=["- 以 `[file: /abs/path]` 开头的文本表示该路径上挂着一个文件,相关时去读它。","- 在回复任意位置,独占一行写 `[[send: /abs/path]]` 即可把该文件作为单独一条消息送出。只在用户主动要文件、或你要交付最终产物时才发。"],rQ=["- 判断是否该发文件:导出附件/数据集、用户明确要文件或下载物时,应先写到本机绝对路径,再用独占一行的 `[[send: /abs/path]]` 发给用户;短总结、普通说明、无需留存的正文答复不要为了发文件而发文件。","- 使用图片生成工具生成图片后,不要再补充说明文字或 `[[send: ...]]`;Lodestar 会根据工具返回的本机图片路径自动发给用户。若你用脚本或文件编辑生成图片,按上一条用 `[[send: /abs/path]]` 发出。","- 每次调用 Bash / shell 命令时,第一行都必须写 shell 注释 `# desc: <一句中文说明>`,再写真正命令。这个注释只给 Lodestar 卡片做摘要,不要依赖它改变命令行为。"],tQ=[...oQ,"- 当你有问题需要澄清时,使用 request_user_input 工具向用户提问;不要把多选题写成文本。",...rQ].join(`
172
+ `),sQ=[...oQ,"- 当你有问题需要澄清时,使用 Claude Code 自带的 AskUserQuestion 工具向用户提问。",...rQ].join(`
173
+ `)});import{execFileSync as BK}from"node:child_process";import{existsSync as H1,readdirSync as qK,readFileSync as LK,realpathSync as U5,statSync as PK}from"node:fs";import{dirname as jK,join as ZW,resolve as s9}from"node:path";async function e9($,Z){let J=U5($),Y=process.platform==="win32"?J.toLowerCase():J,Q=t9.get(Y)??Promise.resolve(),W,H=new Promise((V)=>{W=V}),X=Q.catch(()=>{}).then(()=>H);t9.set(Y,X),await Q.catch(()=>{});try{return await Z()}finally{if(W(),t9.get(Y)===X)t9.delete(Y)}}function X1($){let Z=$.trim();if(!RK.test(Z))return null;return Z}function JW($){return $.match(/^(.+)\[[^\[\]]+\]$/)?.[1]??$}function a1($,Z){return`${$}[${Z}]`}function YW($){return`${n1}${$}`}function o1($,Z,J){return ZW(jK($),a1(Z,J))}function QW($,Z,J){let Y=DK($,Z,J);if(!Y)return null;let Q=LK(Y.path,"utf8").trim();if(!Q)return null;return{path:Y.path,content:Q,slug:Y.slug}}function WW($,Z){E5($);let J=B0($,["for-each-ref","--format=%(refname:short)",`refs/heads/${n1}`]).split(`
174
+ `).map((W)=>W.trim()).filter(Boolean).filter((W)=>W.startsWith(n1)),Y=T5($),Q=[];for(let W of J){let H=W.slice(n1.length);if(!X1(H))continue;let X=a1(Z,H),V=o1($,Z,H),z=Y.get(W)??null,G=!!z&&H1(z),_=zW($,W,G),B={slug:H,chatName:X,branch:W,state:_,expectedPath:V,worktreePath:G?z:null,mounted:G,dirtyCount:null,statusLine:null,error:null};if(z&&H1(z))try{let L=B0(z,["status","--porcelain=v1","--branch"]).split(`
175
+ `).filter(Boolean);B.statusLine=L[0]?.startsWith("## ")?L[0].slice(3):null,B.dirtyCount=L.filter((P)=>!P.startsWith("## ")).length}catch(q){B.error=N5(q)}Q.push(B)}return Q.sort((W,H)=>W.slug.localeCompare(H.slug))}function HW($,Z,J){let Y=X1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);E5($);let Q=YW(Y),W=a1(Z,Y),H=o1($,Z,Y),X=OK($,Q),V=T5($).get(Q)??null,z=X&&!V&&zW($,Q,!1)==="merged"?B0($,["rev-parse","HEAD"]).trim():null;if(V){if(s9(V)!==s9(H))throw Error(`branch ${Q} is already mounted at ${V}`);return VW(H,Q),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!1}}if(H1(H)){if(!PK(H).isDirectory())throw Error(`${H} exists but is not a directory`);if(!X)throw Error(`${H} already exists while branch ${Q} does not`)}if(X){if(B0($,["worktree","add",H,Q]),z)B0(H,["rebase",z]);return{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!1,createdWorktree:!0}}return B0($,["worktree","add","-b",Q,H,"HEAD"]),{slug:Y,chatName:W,branch:Q,worktreePath:H,createdBranch:!0,createdWorktree:!0}}function XW($,Z,J){let Y=O5($,Z,J);if(!H1(Y.worktreePath))return Y;return B0($,["worktree","remove",Y.worktreePath]),{...Y,removedWorktree:!0}}function O5($,Z,J){let Y=X1(J);if(!Y)throw Error(`invalid worktree name "${J}"`);E5($);let Q=YW(Y),W=a1(Z,Y),H=o1($,Z,Y),V=T5($).get(Q)??null??H;if(!H1(V))return{slug:Y,chatName:W,branch:Q,worktreePath:V,removedWorktree:!1};VW(V,Q);let z=B0(V,["status","--porcelain=v1"]).split(`
176
+ `).filter(Boolean);if(z.length>0){let G=z.slice(0,8).join(`
177
177
  `);throw Error(`worktree has uncommitted changes:
178
- ${A}`)}return{slug:Y,chatName:W,branch:Q,worktreePath:V,removedWorktree:!1}}function H5($){if(!Y1($))throw Error(`project directory does not exist: ${$}`);let Z=B$($,["rev-parse","--show-toplevel"]).trim();if(Q5(Z)!==Q5($))throw Error(`${$} is not the git repository root (${Z})`)}function IQ($,Z){let J=B$($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function Z_($,Z,J){let Y=J_($);if(!Y?.startsWith(I1))return null;let Q=Y.slice(I1.length);if(!Q1(Q))throw Error(`invalid worktree branch "${Y}"`);let W=m1(Z,J,Q);if(h6($)!==h6(W))return null;let H=Q_($,Y_(Q));return H?{path:H,slug:Q}:null}function J_($){if(!Y1($))return null;try{return B$($,["branch","--show-current"]).trim()||null}catch(Z){if(H_(Z))return null;throw Z}}function Y_($){return $.split("-",1)[0]??$}function Q_($,Z){let J=`agents.${Z}.md`,Y=rK($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?CQ($,Y[0]):null}function W_($,Z){try{return B$($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function cQ($,Z,J){let Y=B$($,["rev-parse",Z]).trim(),Q=B$($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if(xQ($,Z,"HEAD"))return"merged";if(xQ($,"HEAD",Z))return"active";return"stale"}function xQ($,Z,J){try{return B$($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function X5($){let Z=new Map,J=B$($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
179
- `)){if(Q.startsWith("worktree ")){Y=Q.slice(9);continue}if(Q.startsWith("branch refs/heads/")&&Y)Z.set(Q.slice(18),Y)}return Z}function B$($,Z){try{return oK("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(V5(J))}}function V5($){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 H_($){return/not a git repository/i.test(V5($))}var I1="work/",$_,v6;var mQ=S(()=>{$_=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,v6=new Map});function k0($){return bQ(a$($.sessionName)??$.sessionName)}function u1($){return b4(k0($))}function pQ($){let Z=a$($.sessionName)??$.sessionName,J=k0($),Y=b4(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return m1(Y,J,Q)}function lQ($,Z=$.currentProvider()){let J=Z==="claude"?SQ:kQ,Y=c2($);return Y?`${J}
180
- ${Y}`:J}function iQ($,Z){return c2($)??""}function z5($){return c2($)?"已载入wt特殊约定":null}function dQ($,Z){let J=z5($);return J?`${Z}
181
- ${J}`:Z}function c2($){let Z=k0($),J=wQ($.workDir,u1($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
182
- `)}async function nQ($,Z,J){if(!Z){await G5($);return}let Y=Q1(Z);if(!Y){await N($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await N($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=k0($),W=u1($);try{await g6(W,async()=>{let H;try{H=hQ(W,Q,Y)}catch(X){await N($.chatId,`❌ wt 失败: ${F(X)}`);return}try{let X=await y8(H.chatName,J),V=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await i($.chatId,f2({slug:Y,branch:H.branch,status:V})))await C($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await i(X.chatId,f2({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await C(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await N($.chatId,`❌ wt 已建,拉群失败: ${F(X)}`)}})}catch(H){await N($.chatId,`❌ wt 失败: ${F(H)}`)}}async function aQ($,Z){let J=k0($),Y=u1($);return await g6(Y,async()=>{return await V_(J,Y,Z)})}async function V_($,Z,J){let Y=vQ(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,W=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await f4();return q7({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:W.map((X)=>{let V=H.get(X.chatName)??[],z=J$.get(X.chatName),A=z&&V.includes(z)?z:V.length===1?V[0]:null;return{slug:X.slug,chatName:X.chatName,branch:X.branch,state:X.state,path:X.worktreePath??X.expectedPath,mounted:X.mounted,dirtyCount:X.dirtyCount,statusLine:X.statusLine,error:X.error,chatId:A,duplicateChatCount:V.length}})})}async function G5($){try{let Z=await aQ($);if(!await i($.chatId,Z))await C($.chatId,"❌ wt 列表失败")}catch(Z){await N($.chatId,`❌ wt 列表失败: ${F(Z)}`)}}async function uQ($,Z,J,Y){try{return{ok:Z,message:J,card:await aQ($,{type:Y,content:J})}}catch(Q){let W=`列表刷新失败: ${F(Q)}`;return G(`session "${$.sessionName}": wt action panel refresh failed: ${F(Q)}`),{ok:!1,message:`${J}
183
- ${W}`,card:f2({slug:"wt",branch:"work/*",status:J,body:W,template:"red"})}}}async function oQ($,Z){let J=Q1(Z);if(!J)return uQ($,!1,"❌ 名称无效","error");let Y=k0($),Q=u1($),W;try{W=await g6(Q,async()=>{let H=c1(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};W5(Q,Y,J);let X=await C8(H),V=gQ(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,V.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",V.branch].join(`
184
- `),type:"success"}})}catch(H){W={ok:!1,message:`❌ 解散 ${J} 失败: ${F(H)}`,type:"error"}}return uQ($,W.ok,W.message,W.type)}var rQ=S(()=>{yQ();f$();o();g();mQ()});import{closeSync as G_,openSync as A_,readSync as K_,readdirSync as __,statSync as B_}from"node:fs";import{randomUUID as K5}from"node:crypto";import{join as q_}from"node:path";function c6($){return a$($.sessionName)??$.sessionName}function sQ($){let Z=U8($,A5);return A5.add(Z),Z}function eQ($){A5.delete($)}function p1($){let Z=tQ.get($);if(!Z)Z=new Map,tQ.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let W=Q.status==="consumed"?P_:L_,H=Q.consumedAt??Q.createdAt;if(J-H>W)Z.delete(Y)}return Z}function j_($,Z){return $.provider===Z.provider&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function $W($,Z,J,Y){let Q={id:K5(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:c6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return p1($).set(Q.id,Q),Q}function _5($,Z,J,Y,Q){let W=p1($).get(J);if(!W||W.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||W.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(W.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(W.provider!==$.selectedProvider||W.workDir!==$.workDir||W.sourceSessionId!==$.lastSessionId||!j_(W.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=W.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return W.status="processing",{panel:W,choice:H}}function I6($){$.status="consumed",$.consumedAt=Date.now()}function M_($){return{kind:"fork",source:$.source,through:$}}function F_($){return B2($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function U_($){let Z=q2($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return z$(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function O_($){let Z=e9($),J;try{J=__(Z)}catch(Q){if(Q?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Q?.message??Q}`)}let Y=[];for(let Q of J){if(!Q.endsWith(".jsonl"))continue;let W=Q.slice(0,-6);if(V4("claude",W))continue;let H=q_(Z,Q),X;try{X=B_(H).mtimeMs}catch(V){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${V?.message??V}`)}Y.push({provider:"claude",sessionId:W,cwd:$,preview:T_(H),ts:X})}return Y.sort((Q,W)=>W.ts-Q.ts)}function E_($){let Z=$.slice().sort((Q,W)=>W.ts-Q.ts),J=Date.now()-R_,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(D_,Math.max(10,Y)))}function T_($){let Z="",J=null;try{J=A_($,"r");let Q=Buffer.alloc(65536),W=K_(J,Q,0,65536,0);Z=Q.subarray(0,W).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)G_(J)}let Y="";for(let Q of Z.split(`
185
- `)){let W=Q.trim();if(!W)continue;let H;try{H=JSON.parse(W)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let X=H.content.trim();if(X)return X.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let X=N_(H.message);if(X)Y=X}}return Y.slice(0,80)}function N_($){let Z=$?.content;if(typeof Z==="string")return Z;if(!Array.isArray(Z))return"";for(let J of Z)if(J?.type==="text"&&typeof J.text==="string")return J.text;return""}async function ZW($,Z,J){if(!J){await N($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=F_($),Q=U_($),W=new Map,H=[];for(let A=0;A<Y.length;A++){let K=Y[A];if(A===0&&Q===null)continue;let B=K5(),q=A===0?Q:M_(Y[A-1].checkpoint);W.set(B,{kind:Z,launch:q,branchBase:Q,seedAnchors:Y.slice(0,A),writes:Y.slice(A).flatMap((L)=>L.writes)}),H.push({choiceId:B,preview:K.preview,ts:K.ts})}H.reverse();let X=$W($,Z,J,W),V=L7({projectName:c6($),panelId:X.id,mode:Z,entries:H}),z;try{z=await i($.chatId,V)}catch(A){throw p1($).delete(X.id),A}if(!z)p1($).delete(X.id),await C($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function JW($,Z){return ZW($,"fork",Z)}function YW($,Z){return ZW($,"back",Z)}async function QW($,Z){if(!Z){await N($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():O_($.workDir)}catch(V){await C($.chatId,`❌ 历史会话读取失败: ${V instanceof Error?V.message:V}`);return}let Y=new Map,Q=E_(J).map((V)=>{let z=K5();return Y.set(z,{kind:"resume",launch:{kind:"fork",source:{provider:V.provider,sessionId:V.sessionId,cwd:V.cwd}},sourcePreview:V.preview,sourceTs:V.ts,sourceStatus:V.status}),{choiceId:z,preview:V.preview,ts:V.ts}}),W=$W($,"resume",Z,Y),H=P7({projectName:c6($),panelId:W.id,entries:Q}),X;try{X=await i($.chatId,H)}catch(V){throw p1($).delete(W.id),V}if(!X)p1($).delete(W.id),await C($.chatId,"❌ rs 历史列表发送失败")}async function WW($,Z){if(!Z){await N($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await N($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=sQ(c6($));await N($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Y;try{Y=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{eQ(J)}if(!Y.ok){await N($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await N($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function HW($){if(!a$($.sessionName)){await N($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await N($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await N($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await N($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function XW($,Z,J,Y){let Q=_5($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let X=sQ(W.baseName);G(`session-temp: fork ${$.sessionName} → ${X} (${H.launch.kind})`),await N($.chatId,`\uD83D\uDD31 正在分叉到 ${X}…`);let V;try{V=await $.opts.onCreateTempSession({chatName:X,userOpenId:Y,workDir:W.workDir,routing:W.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{eQ(X)}if(!V.ok)return{ok:!1,message:`分叉失败: ${V.error??"未知"}`};return{ok:!0,message:`已分叉到 ${X};原会话和磁盘文件未回滚`}}catch(X){return{ok:!1,message:`分叉失败: ${X instanceof Error?X.message:X}`}}finally{I6(W)}}async function VW($,Z,J,Y){let Q=_5($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let X="";try{if(!await i($.chatId,D7({projectName:W.baseName,entries:H.writes})))X=";文件变更记录卡发送失败"}catch(A){X=`;文件变更记录卡发送失败: ${A instanceof Error?A.message:A}`}if(G(`session-temp: back ${$.sessionName} (${H.launch.kind}, writes=${H.writes.length})`),!await $.rollbackTo(H.launch,{anchors:H.seedAnchors,base:H.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${X}`};if(W.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${X}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${V$($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{I6(W)}}async function zW($,Z,J,Y){let Q=_5($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;if(H.kind!=="resume")throw I6(W),Error("resume panel contained a non-resume choice");let X=H.launch.source.sessionId,V=$.lastSessionId,z=(K,B)=>({projectName:W.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:X,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:V,newSessionId:K,bindingState:B}),A=(K,B,q,L=null)=>({ok:K,message:B,resumePresentation:z(L,q)});try{if($.isRunning())return A(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return A(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(G(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${X}`),!await $.rollbackTo(H.launch,{anchors:[],base:H.launch,pendingLaunch:H.launch.source.provider==="claude"?{launch:H.launch,previousSessionId:V}:null}))return A(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(H.launch.source.provider==="claude")return A(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let B=$.lastSessionId;if(!B)return A(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(B===X||V&&B===V)return A(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",B);return A(!0,"已创建并接入独立分支;源会话未修改","changed",B)}catch(K){return A(!1,`历史分支创建失败: ${K instanceof Error?K.message:K}`,"unknown")}finally{I6(W)}}var R_=86400000,L_=1800000,P_=3600000,D_=40,tQ,A5;var GW=S(()=>{o();f$();g();M4();z4();R1();tQ=new WeakMap,A5=new Set});import{existsSync as AW}from"node:fs";import{randomBytes as S_,timingSafeEqual as y_}from"node:crypto";import{isAbsolute as x_}from"node:path";function q5($,Z=new Set){if($ instanceof $2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=q5(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return q5($.cause,Z);return null}function C_($){return $.itemId||$.turnId||"__latest__"}function KW($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function b_($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function f_($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function W1(){return v.runtime?.live_elapsed??"bucket"}function BW($,Z){return`${$} (${B0(Date.now()-Z,W1()).label})`}var w_="Thinking...",v_="Writing...",h_="Working...",B5=1e4,m6=120000,g_=50,I_=256,u6=1e4,_W=250,H1;var qW=S(()=>{P1();d9();v0();U$();W8();G$();M4();d0();f$();o();g();R$();X7();M6();U6();h7();_Y();TY();yY();n7();hY();eY();ZQ();GQ();RQ();EQ();rQ();GW();R1();H1=class H1{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;agentCapability=null;procSourceRevisions=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];backgroundCard=null;settlingBackgroundCard=!1;migratingBackgroundCard=null;backgroundRefreshTimer=null;backgroundRefreshTick=null;openingBackground=!1;openingBackgroundOwner=null;backgroundOpenSequence=0;backgroundGeneration=0;backgroundDetailAdded=new Set;backgroundDetailAdding=new Set;lastMainTaskToolUseId=null;pendingRebuildBackgroundCard=!1;bgResumePending=!1;orphanAssistantSegments=[];orphanAssistantCurrent="";bgResumeCardless=!1;pendingPermissions=new Map;pendingAsks=new Map;currentGoal=null;status="stopped";pendingUserMessageCount=0;pendingMidTurnMsgs=[];pendingTurnInputs=[];multiMsgBuffer=null;multiMsgReactions=new Map;lastUserOpenId="";pendingReactionIds=new Map;currentBatchReactionIds=new Map;initCount=0;openingTurn=!1;openingTurnOwner=null;turnOpenSequence=0;turnCloseInflight=new Set;turnCounter=0;userInterrupted=!1;lastSessionId=null;lastSessionRef=null;selectedProvider="claude";selectedModel=null;selectedEffort=null;selectedTokenSourceId=null;modelPanels=new Map;modelCustomPrompt=null;startedAt=0;cumStats={tokens:0,costUsd:0,turns:0};lastTurnDelta=null;currentTurnUsageBaseline=null;currentTurnUsageBaselineKnown=!1;lastTurnUsage=null;usageTotalsSeedUnknown=!1;resumePersistenceError=null;manualContextCompactionPending=!1;taskBoard=[];constructor($,Z,J={}){this.sessionName=$;this.chatId=Z;this.opts=J;H1.all.add(this);let Y=N8($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=e(this.selectedTokenSourceId);if(Q){if(this.selectedProvider=Q.agent,Q.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Q.defaultModel,this.selectedEffort="max";if(Q.id==="claude-native"&&this.selectedModel&&!Q.models.some((H)=>H.model===this.selectedModel))this.selectedModel=Q.defaultModel}if(this.selectedModel)G(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=p0($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)G(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let W=R2($);if(W)if(this.selectedProvider!=="claude")c$($,[],null,null),G(`session "${$}": cleared pending Claude fork after provider changed`);else{z$(W.launch,"claude",this.workDir);let H=this.lastSessionId===W.previousSessionId,X=this.lastSessionRef,V=!H&&X?.provider==="claude"&&X.cwd===this.workDir&&X.sessionId!==W.launch.source.sessionId&&X.sessionId!==W.previousSessionId;if(!H&&!V)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=W,G(`session "${$}": restored ${V?"materialized":"pending"} Claude fork source=${W.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return pQ(this)}isRunning(){return!!this.proc&&this.proc.isAlive()}shouldRevive(){return 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 U4(J==="codex"?"codex":"claude")[0]?.id??null}currentTokenSource(){return e(this.selectedTokenSourceId)}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort}}applyConversationRouting($){if(this.isRunning()||this.currentTurn||this.openingTurn)throw Error("cannot change conversation routing while the session is running");let Z=e($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)c$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=p0(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,T8(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId)}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!j2())throw Error("Codex 未登录 ChatGPT 账号");let $=this.currentTokenSource();if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(X)=>Z.spawnEnv(X):void 0,Y=new L1({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,W=null;try{Q=await Y.listConversations()}catch(X){W=X}let H=null;try{await Y.kill(2000)}catch(X){H=X}if(W&&H)throw AggregateError([W,H],`Codex history query and cleanup failed: ${F(W)}; ${F(H)}`);if(W)throw W;if(H)throw H;return Q??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="claude"){let J=$8(this.workDir,$.sessionId);if(!AW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${V$($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!j2())throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Y=J?.enabled?J:void 0,Q=new L1({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(X)=>Y.spawnEnv(X):void 0}),W=null;try{Z=await Q.readConversationRef($.sessionId)}catch(X){W=X,Z=$}let H=null;try{await Q.kill(2000)}catch(X){H=X}if(W&&H)throw AggregateError([W,H],`Codex legacy resume lookup and cleanup failed: read=${F(W)}; cleanup=${F(H)}`);if(W)throw W;if(H)throw H}return z$({kind:"resume",source:Z},this.selectedProvider,this.workDir),_2(this.sessionName,Z),Z}hasRunningPeerSession($){return[...H1.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)return;return k$(this.selectedEffort)?this.selectedEffort:J2}return J2}claudeEffortForSpawn(){return this.selectedProvider==="claude"&&n$(this.selectedEffort)?this.selectedEffort:q0}currentModelLabel(){return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){return this.selectedEffort??this.proc?.lastEffort??(this.selectedProvider==="claude"?q0:J2)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Y=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Q=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?q0:J2);return{provider:Z,model:Y,effort:Q}}modelEffortLabel($=this.currentTurn??this.runtimeModelSelection()){let Z=$.provider==="claude"?$.model?.replace(/^claude:/i,"").replace(/\[1m\]$/i,""):$.model,J=Z?`${Z}/${$.effort}`:$.effort;return $.provider==="claude"?`${Z0($.provider)} · ${J}`:J}withModel($,Z){let J=this.modelEffortLabel(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return n($,M.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:M.footer,content:$.trim()||" "}}modelLine($){return this.modelEffortLabel($)}backendLabel($=this.selectedProvider){return Z0($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(z$($.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=S_(32).toString("base64url");let Z={LODESTAR_AGENT_URL:T4(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:this.agentCapability,LODESTAR_AGENT_SESSION:this.sessionName,LODESTAR_AGENT_ROLE:"main"},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});z$(J,this.selectedProvider,this.workDir);let Y=this.currentTokenSource();if(this.selectedTokenSourceId&&(!Y||!Y.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let Q=Y?.enabled?Y:void 0,W=E4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:Q?.id??null,model:Q?this.selectedModel??Q.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:T1(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x0},hostEnv:Z});return this.procSourceRevisions.set(W.process,W.sourceRevision),W.process}async applyModelSelection($,Z,J,Y){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Y))}async applyModelSelectionUnlocked($,Z,J,Y){if(this.selectedProvider!==$)c$(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let W=e(this.selectedTokenSourceId);if(W)this.selectedModel=Z||null,this.selectedEffort=J??W.models.find((H)=>H.model===Z)?.defaultEffort??W.models[0]?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=p0(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,E8(this.sessionName,$,this.selectedModel,this.selectedEffort,this.selectedTokenSourceId),await this.stopIdleMismatchedProcessUnlocked()}async stopIdleMismatchedProcess(){await this.runLifecycle("stop-idle-mismatched",()=>this.stopIdleMismatchedProcessUnlocked())}async stopIdleMismatchedProcessUnlocked(){if(!this.proc?.isAlive())return;let $=this.currentTokenSource(),Z=!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===($?.spawnRevision??null);if(this.proc.provider===this.selectedProvider&&this.proc.tokenSourceId===this.selectedTokenSourceId&&Z)return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let J=this.proc;G(`session "${this.sessionName}": stop idle ${J.provider} process after switching to ${this.selectedProvider}`),this.beginProcStop(J),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let Y=await this.settleProcResumableState(J),Q=null;try{await J.kill(1000)}catch(X){Q=X}Y=await this.settleProcResumableState(J);let W=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!W?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Y?[Error(Y)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(F).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;G(`session "${this.sessionName}": stop idle ${Z.provider} process: ${$}`),this.beginProcStop(Z),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let J=await this.settleProcResumableState(Z),Y=null;try{await Z.kill(1000)}catch(H){Y=H}J=await this.settleProcResumableState(Z);let Q=this.finishProcStop(Z,Y);this.opts.onLifecycleChange?.();let W=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(W.length===1)throw W[0];if(W.length>1)throw AggregateError(W,`idle process stop failed: ${W.map(F).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,W=!1,H=()=>{if(W)return;this.replaceFooterContent($,J(BW(Q,Y)))},X=null,V=()=>{if(W)return;let{nextDelayMs:z}=B0(Date.now()-Y,W1());X=setTimeout(()=>{H(),V()},Math.max(1,Math.ceil(z)))};return H(),V(),{setStatus(z){Q=z,H()},stop(){if(W=!0,X)clearTimeout(X)},elapsedSec(){return((Date.now()-Y)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=V7({sessionName:this.sessionName,title:$,status:BW(Z,Y),template:J}),W=await i(this.chatId,Q);if(!W)return G(`session "${this.sessionName}": status card send failed title=${$}`),await C(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await o$(W)}catch(X){return G(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await C(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return u$(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>C2($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=C2($.title,`${Z} (${J}s)`);await x$($.cardId);let Q=await D$($.cardId,M.footer,this.footerElement(Y));A$($.cardId);let W=await K$($.cardId,z0({durationSec:J,suffix:Z}));if(Q&&W)await C$($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${W?"ok":"MISS"}`;G(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await C(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Y;this.lifecycleTail=new Promise((W)=>{Y=W}),await J;let Q=++this.lifecycleSequence;G(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),G(`session "${this.sessionName}": lifecycle#${Q} ${$} end`)}}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){if(this.openingTurnOwner)throw Error(`turn card open already owned by token=${this.openingTurnOwner.token}; same-process opens must wait for the current owner`);let Y,Q=new Promise((H)=>{Y=H}),W={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=W,this.openingTurn=!0,W}ownsTurnOpen($){return this.openingTurnOwner===$&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseTurnOpen($){if(this.openingTurnOwner!==$)return;this.openingTurnOwner=null,this.openingTurn=!1,$.resolveDone()}invalidateTurnOpen(){let $=this.openingTurnOwner;this.openingTurnOwner=null,this.openingTurn=!1,$?.resolveDone()}async waitForTurnOpenSlot($,Z){while(this.openingTurnOwner)if(await this.openingTurnOwner.done,this.proc!==$||this.procEpoch!==Z||!$.isAlive())return!1;return this.proc===$&&this.procEpoch===Z&&$.isAlive()}beginBackgroundOpen(){if(this.backgroundCard||this.openingBackgroundOwner)return null;let $={token:++this.backgroundOpenSequence,proc:this.proc,procEpoch:this.procEpoch,generation:this.backgroundGeneration};return this.openingBackgroundOwner=$,this.openingBackground=!0,$}ownsBackgroundOpen($){return this.openingBackgroundOwner===$&&this.backgroundGeneration===$.generation&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseBackgroundOpen($){if(this.openingBackgroundOwner!==$)return;this.openingBackgroundOwner=null,this.openingBackground=!1}invalidateBackgroundOpen(){this.backgroundGeneration++,this.openingBackgroundOwner=null,this.openingBackground=!1}attachProc($){this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.stoppingProc=null,this.blockedProc=null,this.blockedProcReason=null,this.proc=$;let Z=++this.procEpoch;this.wireProc($,Z)}detachProc($){if(this.proc!==$)return!1;if(this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.proc=null,this.agentCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.agentCapability=null}acceptsAgentCapability($){let Z=this.agentCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Y=Buffer.from($);return J.length===Y.length&&y_(J,Y)}async cancelAgentRuns($="用户取消"){await this.opts.onCancelAgentRuns?.(this.sessionName,this.chatId,$)}finishProcStop($,Z){if(this.stoppingProc===$)this.stoppingProc=null;if(!$.isAlive())return this.discardPendingCodexTurnAnchors($,"confirmed process stop"),this.detachProc($),!0;return this.blockedProc=$,this.blockedProcReason=Z?F(Z):"kill returned while process still reports alive",G(`session "${this.sessionName}": process stop unconfirmed; lifecycle blocked: ${this.blockedProcReason}`),!1}blockedProcessMessage(){let $=this.blockedProc;if(!$)return null;if(!$.isAlive())return this.detachProc($),null;return`旧 ${this.backendLabel($.provider)} 进程尚未确认退出,会话已阻断: ${this.blockedProcReason??"未知原因"}`}async stopOwnedProc($,Z){if(this.proc!==$)return!$.isAlive();this.beginProcStop($);let J=null;try{await $.kill(Z)}catch(Y){J=Y}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(W){Z=`Codex 会话落盘确认失败: ${F(W)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${F(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.turnCounter=0,this.pendingConversationMaterialization=null,c$(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 startUnlocked($={}){let Z=$.announce??!0,J=$.onStatus,Y=this.blockedProcessMessage();if(Y){if(this.status="stopped",J?.(`❌ ${Y}`),Z)await N(this.chatId,`❌ ${Y}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&!j2()){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z)await N(this.chatId,"❌ Codex 未登录 ChatGPT 账号。\n请在服务器上运行 `codex login` 后再试。");return!1}if(!AW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await N(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{h8(this.workDir)}catch(A){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${A}`),Z)await N(this.chatId,`❌ 创建项目失败: ${A}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Q;try{await O4(),Q=this.spawnAgent()}catch(A){let K=`${this.backendLabel()} 启动失败: ${F(A)}`;if(G(`session "${this.sessionName}": ${K}`),J?.(`❌ ${K}`),Z)await N(this.chatId,`❌ ${K}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let W=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,_W):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${W} 启动`:`⏳ 等待 ${W} init`);let X,V=null;try{if(Q.sendInitialize(),this.selectedProvider==="codex")X=Q.initializationPromise?.()}catch(A){X=void 0,V=A}let z=V?{state:"error",error:V}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(X),()=>{G(`session "${this.sessionName}": codex init still pending after ${B5/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${W} init 确认`))});if(z.state==="error"||z.state==="exit"){let A=z.error?F(z.error):z.state;G(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${A}`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,q=`❌ ${W} 启动失败: ${A}${B}`;if(J?.(q),Z)await N(this.chatId,q);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(z.state==="timeout"){G(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${m6/1000}s)`);let K=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${W} 启动超时: ${m6/1000} 秒内初始化事务未完成${K}`;if(J?.(B),Z)await N(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let A=`${W} 启动期间已退出`;if(G(`session "${this.sessionName}": ${A}`),J?.(`❌ ${A}`),Z)await N(this.chatId,`❌ ${A}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(Z){let A=this.modelLine();await N(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),A].filter(Boolean).join(`
186
- `))}return this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Y=!1,Q=(X,V)=>{if(Y)return;Y=!0,clearTimeout(W),clearTimeout(H),J({state:X,error:V})},W=setTimeout(()=>{if(Y)return;try{Z?.()}catch(X){Q("error",X)}},B5),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${m6/1000}s`))},m6);$.then(()=>Q("init"),(X)=>Q("error",X))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(z,A)=>{if(Y)return;Y=!0,clearTimeout(W),$.off("init",H),$.off("error",X),$.off("exit",V),J({state:z,error:A})},W=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),X=(z)=>Q("error",z),V=(z)=>Q("exit",z);$.once("init",H),$.once("error",X),$.once("exit",V)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)P$($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;G(`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)P$(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}async stopUnlocked($="已终止",Z={}){let J=Z.announce??!0,Y=Z.onStatus;if(await this.cancelAgentRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.("⚪ session 当前未运行"),J)await N(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Q=this.proc,W=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),G(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((D)=>{G(`session "${this.sessionName}": stop current main-card close failed: ${F(D)}`)});let X=this.waitForTurnCloses().catch((D)=>G(`session "${this.sessionName}": stop main-card close failed: ${F(D)}`));this.beginProcStop(Q),this.status="stopped";let V=[];try{this.opts.onLifecycleChange?.()}catch(D){V.push(D),G(`session "${this.sessionName}": stop intent lifecycle write failed: ${F(D)}`)}let z=Q.conversationMaterializationBarrier?.();if(z){try{await z}catch(D){H=`Codex 会话落盘确认失败: ${F(D)}`}W=this.persistResumableSessionId(!1,Q,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let A=null;try{await Q.kill()}catch(D){A=D}let K=Q.conversationMaterializationFailure?.();if(K&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${F(K)}`;W=this.persistResumableSessionId(!1,Q,!1);let q=(await Promise.allSettled([this.resetBackgroundTasks(),X])).filter((D)=>D.status==="rejected").map((D)=>D.reason);for(let D of q)G(`session "${this.sessionName}": stop terminal cleanup failed: ${F(D)}`);let L=this.finishProcStop(Q,A);try{this.opts.onLifecycleChange?.()}catch(D){V.push(D),G(`session "${this.sessionName}": stop final lifecycle write failed: ${F(D)}`)}let R=[...A?[A]:[],...!L&&!A?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...q,...V,...W?[Error(W)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(R.length===1)throw R[0];if(R.length>1)throw AggregateError(R,`stop failed: ${R.map(F).join("; ")}`);if(Y?.(`✅ ${$}`),J)await N(this.chatId,`\uD83D\uDD34 ${$} (session: ${this.sessionName})`)}async restart($=!1,Z={}){return await this.runLifecycle("restart",()=>this.restartUnlocked($,Z))}async restartUnlocked($=!1,Z={},J){let Y=Z.announce??!0,Q=Z.onStatus,W=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,L0(this.sessionName,null),this.pendingConversationMaterialization=null;let X=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),V=this.lastSessionRef;if($&&!X&&V?.cwd===null)try{V=await this.resolveLegacyResumeRef(V),this.lastSessionRef=V,this.lastSessionId=V.sessionId}catch(T){let k=this.invalidateMissingCodexResume(V.sessionId,T,J),u=k?`❌ 旧会话不可恢复: ${F(T)};${k}`:`❌ 旧会话 cwd 校验失败: ${F(T)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?W:"stopped",Q?.(u),Y)await N(this.chatId,u);return!1}let z=V?.sessionId??null,A=X&&X.kind!=="fresh"?X.source.sessionId:z,K=A?V$(A):"",B=null,q=(T=this.proc)=>{if(!$||X||T?.provider!=="codex"||T.isConversationResumable?.()!==!0)return;B=this.persistResumableSessionId(!1,T,!1),V=this.lastSessionRef,z=V?.sessionId??null,A=z,K=A?V$(A):""},L=null;if(!Q&&Y&&$&&z){let T=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`);if(L=await this.openStatusCard("restart",T),L)Q=(k)=>this.setStatusCard(L,k)}let R=Y&&!L,D=async(T)=>{if(L)await this.closeStatusCard(L,T)},U=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||this.backgroundTasks.length>0||this.pendingBgTasks.length>0||this.openingBackground);if(this.bgResumePending=!1,this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.discardOrphanAssistant(),this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((T)=>{G(`session "${this.sessionName}": restart current main-card close failed: ${F(T)}`)});let P=this.waitForTurnCloses().catch((T)=>G(`session "${this.sessionName}": restart main-card close failed: ${F(T)}`)),j=null,O=null;if(this.proc){let T=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(T.provider)}`),O=T,this.beginProcStop(T);let k=T.conversationMaterializationBarrier?.();if(k)try{await k}catch(E){B=`Codex 会话落盘确认失败: ${F(E)}`}if(q(T),$&&!X&&B&&!U&&T.isAlive()){if(this.stoppingProc===T)this.stoppingProc=null;this.status=W;let E=`❌ ${this.backendLabel(T.provider)} 恢复点尚未安全落盘,已保留当前进程: ${B}`;if(G(`session "${this.sessionName}": abort restart before kill: ${B}`),Q?.(E),R)await N(this.chatId,E);return await D(E),!1}try{await T.kill()}catch(E){j=E}let u=T.conversationMaterializationFailure?.();if(u&&T.isConversationResumable?.()!==!0)B=`Codex 会话落盘确认失败: ${F(u)}`;q(T)}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let x=(await Promise.allSettled([this.resetBackgroundTasks(),P])).filter((T)=>T.status==="rejected").map((T)=>T.reason);for(let T of x)G(`session "${this.sessionName}": restart terminal cleanup failed: ${F(T)}`);let m=O?this.finishProcStop(O,j):!0,h=[...j?[`kill=${F(j)}`]:[],...!m&&!j?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...x.map((T)=>`cleanup=${F(T)}`),...B?[`resume=${B}`]:[]];if(h.length>0&&H)try{L0(this.sessionName,H),this.pendingConversationMaterialization=H}catch(T){h.push(`pendingRestore=${F(T)}`)}if(h.length>0){let T=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${h.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(T),R)await N(this.chatId,T);return await D(T),!1}let I=X?.kind==="resume"||X?.kind==="fork";if($&&V||I){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${K}`));let T;try{await O4(),T=this.spawnAgent(V??void 0)}catch(W$){let F$=`❌ ${this.backendLabel()} 恢复失败: ${F(W$)}`;if(G(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${F(W$)}`),Q?.(F$),R)await N(this.chatId,F$);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(F$),!1}this.attachProc(T);let k=this.backendLabel(),u=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(T,_W):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${k} 恢复启动`:`⏳ 等待 ${k} init 确认`);let E,y=null;try{if(T.sendInitialize(),this.selectedProvider==="codex")E=T.initializationPromise?.()}catch(W$){E=void 0,y=W$}let f=y?{state:"error",error:y}:this.selectedProvider==="claude"?await u:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(E),()=>{G(`session "${this.sessionName}": codex resume init still pending after ${B5/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${k} init 确认 thread=${K}`))});if(f.state==="error"||f.state==="exit"||f.state==="timeout"){let W$=f.state==="error"?this.invalidateMissingCodexResume(A,f.error,J):null,F$=[f.error?F(f.error):f.state,W$].filter(Boolean).join(";");G(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${F$}`);let r1=await this.stopOwnedProc(T,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,v$=f.state==="timeout"?`❌ ${k} 恢复超时${r1}`:`❌ ${k} 恢复失败: ${F$}${r1}`;if(Q?.(v$),R)await N(this.chatId,v$);return this.status="stopped",this.opts.onLifecycleChange?.(),await D(v$),!1}if(this.proc!==T||!T.isAlive()){let W$=`❌ ${k} 恢复期间已退出`;if(G(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(W$),R)await N(this.chatId,W$);return this.detachProc(T),this.status="stopped",this.opts.onLifecycleChange?.(),await D(W$),!1}let M$=this.withModel(this.withWorktreeInstructionNotice(this.selectedProvider==="claude"&&f.state==="ready"?`✅ 已准备恢复上一会话 thread=${K}`:`✅ 已恢复上一会话 thread=${K}`));if(Q?.(M$),R)await N(this.chatId,M$);this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.();try{await D(M$)}catch(W$){G(`session "${this.sessionName}": restart succeeded but status-card close failed: ${F(W$)}`),await C(this.chatId,`⚠️ ${M$}
187
- 状态卡收尾失败: ${F(W$)}`)}return!0}else{if($&&!X){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),R)await N(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{z$($,this.selectedProvider,this.workDir);let J=R2(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)L0(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)L0(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{L0(this.sessionName,J),this.pendingConversationMaterialization=J}catch(W){throw AggregateError([Q,W],`fork start and pending-intent restore failed: ${F(Q)}; ${F(W)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{z$($,this.selectedProvider,this.workDir);let Y=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Q=this.proc,W=this.lastSessionId,H=this.lastSessionRef,X=B2(this.sessionName).slice(),V=q2(this.sessionName),z=R2(this.sessionName),A={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,B=()=>{if(K)this.lastSessionId=null,this.lastSessionRef=null,N1(this.sessionName,"codex");else if(this.lastSessionId=W,this.lastSessionRef=H,H)_2(this.sessionName,H);else N1(this.sessionName,this.selectedProvider);c$(this.sessionName,X,V,z),this.pendingConversationMaterialization=z,this.turnCounter=A.turnCounter,this.currentGoal=A.currentGoal,this.cumStats=A.cumStats,this.lastTurnDelta=A.lastTurnDelta,this.currentTurnUsageBaseline=A.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=A.currentTurnUsageBaselineKnown,this.lastTurnUsage=A.lastTurnUsage,this.usageTotalsSeedUnknown=A.usageTotalsSeedUnknown},q=!1;if(Y?.pendingLaunch)c$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,q=!0;this.pendingConversationLaunch=$;let L=(R)=>{K=H?.provider==="codex"&&H.sessionId===R};try{let R;try{R=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(D){let U=null,P=this.proc&&this.proc!==Q?this.proc:null;if(P)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(x){U=x}let j=!P||this.proc!==P&&!P.isAlive();if(!j&&!U)U=Error("replacement process stop was not confirmed");let O=null;if(j)try{B()}catch(x){O=x}let b=[D,...U?[U]:[],...O?[O]:[]];if(b.length===1)throw D;throw AggregateError(b,`rollback launch and cleanup failed: ${b.map(F).join("; ")}`)}if(!R)return B(),!1;if(Y)try{if(!q)c$(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(D){let U=null,P=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(x){U=x}let j=!P||this.proc!==P&&!P.isAlive();if(!j&&!U)U=Error("replacement process stop was not confirmed");let O=null;if(j)try{B()}catch(x){O=x}let b=[D,...U?[U]:[],...O?[O]:[]];if(b.length===1)throw D;throw AggregateError(b,`rollback branch commit failed: ${b.map(F).join("; ")}`)}return R}finally{this.pendingConversationLaunch=null}})}dispose(){H1.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Y=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return G(`session "${this.sessionName}": ${Y}`),this.lastTurnUserPreview="",Y}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Q)=>Q.proc===Z).length>=64)return G(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),G(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return F8(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${F(Z)}`;return G(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Y of this.pendingCodexTurnAnchors){if(Y.proc!==$||Z){J.push(Y);continue}if(Z=this.appendTurnAnchor(Y.anchor),Z)J.push(Y)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Q)=>Q.proc!==$);let Y=J-this.pendingCodexTurnAnchors.length;if(Y>0)G(`session "${this.sessionName}": dropped ${Y} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...F7(J.name,J.input));return Z}worktreeProjectName(){return k0(this)}worktreeProjectDir(){return u1(this)}spawnDeveloperInstructions(){return lQ(this)}delegatedAgentDeveloperInstructions($){return iQ(this,$)}worktreeInstructionLoadedNotice(){return z5(this)}withWorktreeInstructionNotice($){return dQ(this,$)}worktreeExtraInstruction(){return c2(this)}runWorktreeCommand($,Z){return nQ(this,$,Z)}showWorktrees(){return G5(this)}showTasklistPanel(){return MQ(this)}showAgentIdentityPanel($=""){return KQ(this,$)}onAgentIdentityPage($,Z,J){return _Q($,Z,J)}onTasklistEnable(){return FQ(this)}onTasklistDeletePrompt($){return UQ(this,$)}onTasklistDeleteConfirm($){return OQ(this,$)}runCompactCommand(){return $Q(this)}showModelPanel(){return YQ(this)}onModelSelect($,Z="",J="",Y=null){return VQ(this,$,Z,J,Y)}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>zQ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return QQ(this,$,Z)}onModelPanelCancel($=""){return XQ(this,$)}onModelCustomPrompt($,Z,J=""){return WQ(this,$,Z,J)}consumeModelCustomMessage($,Z){return HQ(this,$,Z)}onWorktreeDisband($){return oQ(this,$)}showForkList($=""){return JW(this,$)}showBackList($=""){return YW(this,$)}showResumeList($=""){return QW(this,$)}runBtwCommand($){return WW(this,$)}runByeCommand(){return HW(this)}onForkSelect($,Z,J=""){return XW(this,$,Z,J)}onBackSelect($,Z,J=""){return VW(this,$,Z,J)}onResumeSelect($,Z,J=""){return zW(this,$,Z,J)}runCommand($,Z=""){return sY(this,$,Z)}async buildConsoleOpts($,Z){let J=await kJ(),Y=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Y.provider,model:Y.model??void 0,effort:Y.effort,worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...H1.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return z7(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Y=this.currentTokenSource(),Q=Y&&Y.agent===J&&Y.enabled?Y:this.selectedTokenSourceId?void 0:U4(J)[0];if(Q)Z.unifiedUsage=await Q.readUsage();else if(this.selectedTokenSourceId)Z.unifiedUsage={state:"no_credentials",windows:[],reason:`token source ${this.selectedTokenSourceId} unavailable`};else if(Z.provider==="claude")Z.glmUsage=await v7();else Z.usage=await j6();if(!await D$($,M.consoleUsage,b2(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(W){Y=!1,G(`session "${this.sessionName}": ${Z} mutation failed: ${F(W)}`)}let Q=!1;try{Q=await K$($,{config:{streaming_mode:!1}})}catch(W){G(`session "${this.sessionName}": ${Z} streaming-off failed: ${F(W)}`)}if(!Y||!Q)return G(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await C$($)}catch(W){return G(`session "${this.sessionName}": ${Z} dispose failed: ${F(W)}`),!1}return Y}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Y=await this.buildConsoleOpts(void 0);await x$($.cardId);let Q=await D$($.cardId,M.footer,W6(Y,M.footer)),W=await D0($.cardId,Q6(Y),{type:"insert_after",targetElementId:M.footer}),H=await D0($.cardId,H6(Y.sysinfo),{type:"insert_after",targetElementId:M.consoleProjects}),X=await D0($.cardId,b2(Y),{type:"insert_after",targetElementId:M.consoleHost});if(!Q||!W||!H||!X){await C(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}A$($.cardId),await K$($.cardId,z0({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await i(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await o$(Z),u$(J,4)}catch(Y){G(`session "${this.sessionName}": console card conversion failed: ${F(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>G(`session "${this.sessionName}": console async update rejected: ${F(J)}`))}interrupt(){if(!this.proc)return;G(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){this.pendingUserMessageCount++;try{$.sendUserText(Z,[])}catch(J){throw this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),J}}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Y=this.beginTurnOpen();try{let W=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!W||this.currentTurn!==W)return;let H=this.startFooterTimer(W.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(A)=>this.withModel(A)),X=`\uD83D\uDE80 启动 ${this.backendLabel()}`,V=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(A)=>{X=A,H.setStatus(A)}});if(H.stop(),await x$(W.cardId),!V){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(X.startsWith("❌")?X:"❌ 启动失败",{forcePush:!0});return}let z=this.proc;if(!z?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(W),this.sendClaimedUserText(z,Z),this.status="working"}finally{this.releaseTurnOpen(Y)}}async onUserMessage($,Z=[],J="",Y=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Y))}async onUserMessageUnlocked($,Z,J,Y){let Q=this.blockedProcessMessage();if(Q){await N(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.clearStaleIdleQueueState("user_message"),this.proc?.isAlive()&&!this.currentTurn&&!this.openingTurn&&this.pendingUserMessageCount===0&&this.pendingMidTurnMsgs.length===0)await this.stopIdleMismatchedProcessUnlocked();let W=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let X=(Z.length?Z.map((z)=>`[file: ${z}]`).join(" ")+`
188
- `:"")+$,V=(z)=>{this.pendingReactionIds.set(z,""),(async()=>{let A=await T$(z,"OneSecond");if(!A)return;if(this.pendingReactionIds.has(z))this.pendingReactionIds.set(z,A);else if(this.currentBatchReactionIds.has(z))this.currentBatchReactionIds.set(z,A);else P$(z,A)})().catch((A)=>{G(`session "${this.sessionName}": reaction tracking failed: ${F(A)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}await this.startColdUserTurn($,X,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}if(!this.openingTurn&&this.initCount>=1){let z=this.proc,A=this.procEpoch,K=this.beginTurnOpen(z,A);try{this.pendingTurnInputs.push($);let B=await this.openTurnCard(K,J,"user_message");if(!B||this.currentTurn!==B)return;if(this.proc!==z||this.procEpoch!==A||!z.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(z.provider)} 已退出`);return}this.sendClaimedUserText(z,X),this.status="working"}finally{this.releaseTurnOpen(K)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,X),W&&Y)V(Y)}hasPendingAsk(){return xY(this)}onMultiMessageInbound($,Z,J,Y){return KY(this,$,Z,J,Y)}clearMultiMsgBuffer($){I7(this,$)}onAskMessageAnswer($,Z,J){return CY(this,$,Z,J)}onAskAnswer($,Z,J,Y){return bY(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return i7(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return wY(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=p0(this.sessionName,"codex");if(N1(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)G(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=q5(Z);if(!Y||!["thread/read","thread/resume","thread/fork"].includes(Y.method)||Y.serverCode!==-32600||Y.serverMessage!==`no rollout found for thread id ${$}`)return null;let Q=p0(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{N1(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${F(H)}`;return G(`session "${this.sessionName}": ${X} thread=${$}`),X}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let W=`已作废无 rollout 的恢复点 thread=${V$($)}`;return G(`session "${this.sessionName}": ${W} fullThread=${$}`),W}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Y=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Q=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Q){if(!Y)return null;let X=Error("Claude pending fork did not provide a materialized session id");if(G(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}let W={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let X=Error(`Claude fork did not materialize an independent session id (${Q})`);if(G(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}try{_2(this.sessionName,W)}catch(X){let V=`会话恢复点持久化失败: ${F(X)}`,z=this.resumePersistenceError!==V;if(this.resumePersistenceError=V,Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;if(G(`session "${this.sessionName}": ${V}`),$)throw X;if(z&&J)C(this.chatId,`⚠️ ${V};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return V}if(Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let X=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(X&&J)C(this.chatId,`⚠️ ${H}`);return H}return this.resumePersistenceError=null,null}consumePendingConversationMaterialization(){let $=this.pendingConversationMaterialization;if(!$)return null;let Z=this.lastSessionRef;if(Z?.provider!=="claude"||Z.cwd!==this.workDir||Z.sessionId===$.launch.source.sessionId||Z.sessionId===$.previousSessionId)return G(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return L0(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${F(J)}`;return G(`session "${this.sessionName}": ${Y}`),Y}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(I9(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}onBackgroundTaskChanged(){if(this.migratingBackgroundCard){this.pendingRebuildBackgroundCard=!0;return}if(!w0(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{G(`session "${this.sessionName}": background settle failed: ${F(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{G(`session "${this.sessionName}": background open failed: ${F(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=l9(Z,Date.now(),W1()),Y=await i(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))G(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await o$(Y)}catch(W){G(`session "${this.sessionName}": background card id_convert failed: ${W}`);return}if(u$(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((W)=>W.id)),this.backgroundDetailAdding.clear(),G(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!w0(this.backgroundTasks)){this.settleBackgroundCard().catch((W)=>{G(`session "${this.sessionName}": background settle-after-open failed: ${F(W)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!w0(this.backgroundTasks))return;let Z=W1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(y$(Q))continue;let W=B0(J-Q.startedAt,Z).nextDelayMs;if(W<Y)Y=W}if(!isFinite(Y))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Y)))};$()}stopBackgroundRefreshTick(){if(this.backgroundRefreshTick)clearTimeout(this.backgroundRefreshTick),this.backgroundRefreshTick=null}scheduleBackgroundRefresh(){if(!this.backgroundCard||this.settlingBackgroundCard||this.migratingBackgroundCard)return;if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull()},1500)}refreshBackgroundCardFull(){if(this.migratingBackgroundCard)return;let $=this.backgroundCard;if(!$)return;let Z=Date.now(),J=W1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),D0($.cardId,D1(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else G(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else n($.cardId,Y2.panel(Y.id),D1(Y,Z,J));H0($.cardId,B4(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!y$($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>y$(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$})}if(this.pendingBgTasks=[],this.backgroundCard)await this.settleBackgroundCard();if(this.stopBackgroundRefreshTick(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.backgroundTasks=[],this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear()}async settleBackgroundCard(){if(this.migratingBackgroundCard)try{await this.migratingBackgroundCard}catch(J){G(`session "${this.sessionName}": background migration failed before settle; retry terminal snapshot: ${F(J)}`)}let $=this.backgroundCard;if(!$||this.settlingBackgroundCard)return;this.settlingBackgroundCard=!0;let Z=[...this.backgroundTasks];if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.stopBackgroundRefreshTick();try{if(await x$($.cardId),await Q0($.messageId,q4(Z)),A$($.cardId),!await K$($.cardId,z0({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await C$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!y$(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),G(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&w0(this.backgroundTasks))this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(this.backgroundTasks.length>0)this.onBackgroundTaskChanged()}migrateBackgroundCard(){if(this.migratingBackgroundCard)return this.migratingBackgroundCard;let $=this.backgroundCard;if(!$)return Promise.resolve();let Z=this.performBackgroundCardMigration($),J;return J=Z.finally(()=>{if(this.migratingBackgroundCard===J)this.migratingBackgroundCard=null}),this.migratingBackgroundCard=J,J}async performBackgroundCardMigration($){if(this.backgroundCard!==$)return;if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;if(this.stopBackgroundRefreshTick(),await x$($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(y$).map((W)=>W.id)),Y=J.size;if(Y>0)await Q0($.messageId,q4(Z));else await Q0($.messageId,i9());if(A$($.cardId),!await K$($.cardId,z0({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await C$($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((W)=>!J.has(W.id)||!y$(W)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),G(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Y} active=${this.backgroundTasks.length}`)}startScheduledTurnCard($,Z,J,Y){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Q;try{Q=this.beginTurnOpen($,Z,!0)}catch(H){G(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${F(H)}`);return}let W=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${W.slice(0,78)}`,G(`session "${this.sessionName}": scheduled wakeup prompt=${Y??"MISS"}`),(async()=>{try{let H=await this.openTurnCard(Q,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(G(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),H&&this.currentTurn===H)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!H||this.currentTurn!==H){if(!this.ownsTurnOpen(Q))return;if(this.bgResumeCardless=!0,Q.sawResult)Q.sawResult=!1,G(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else G(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,G(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Q.terminalSuffix,{forcePush:Q.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Q)}})().catch((H)=>{G(`session "${this.sessionName}": scheduled turn-open handler failed: ${F(H)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Y=()=>this.proc===$&&this.procEpoch===J,Q=!1,W=!1,H=(X,V)=>{$.on(X,(z)=>{if(!Y()){if(!Q)Q=!0,G(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(X)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(X!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!W)W=!0,G(`session "${this.sessionName}": ignore ${$.provider} event=${String(X)} while process stop is pending`);return}V(z)})};H("error",(X)=>{G(`session "${this.sessionName}": ${$.provider} process error: ${X}`)}),H("init",()=>{if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,G(`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)G(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let X=this.pendingUserMessageCount>0,V=!X&&this.bgResumePending;if(!X&&!V)return;let z=this.lastUserOpenId,A;try{A=this.beginTurnOpen($,J,!0)}catch(q){G(`session "${this.sessionName}": init turn-open ownership conflict: ${F(q)}`);return}if(this.bgResumePending=!1,X)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let K=X?[...this.currentBatchReactionIds.keys()]:[],B=()=>{for(let q of K){let L=this.currentBatchReactionIds.get(q);if(this.currentBatchReactionIds.delete(q),L)P$(q,L)}};(async()=>{try{let q=await this.openTurnCard(A,z,X?"user_message":"bg_task_resume");if(!Y()){if(G(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),q&&this.currentTurn===q)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);B();return}if(!q||this.currentTurn!==q){if(!this.ownsTurnOpen(A)){B();return}if(A.sawResult&&A.terminalSuffix)C(this.chatId,A.terminalSuffix);if(X)G(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),B();else if(this.bgResumeCardless=!0,A.sawResult)A.sawResult=!1,G(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else G(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(A.sawResult)A.sawResult=!1,G(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(A.terminalSuffix,{forcePush:A.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(A)}})().catch((q)=>{G(`session "${this.sessionName}": init turn-open handler failed: ${F(q)}`)})}),H("scheduled_turn_input",({text:X,promptId:V})=>{if($.provider!=="claude")return;this.startScheduledTurnCard($,J,X,V)}),H("conversation_materialized",({session_id:X,source:V})=>{if($.provider!=="codex")return;if($.sessionId!==X){G(`session "${this.sessionName}": ignore mismatched Codex materialization session=${X} current=${$.sessionId??"MISS"} source=${V}`);return}G(`session "${this.sessionName}": Codex resume point materialized thread=${X} source=${V}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:X,source:V,error:z})=>{if($.provider!=="codex"||$.sessionId!==X)return;let A=`Codex 会话落盘确认失败,未写恢复点: ${F(z)}`,K=this.resumePersistenceError!==A;if(this.resumePersistenceError=A,G(`session "${this.sessionName}": ${A} thread=${X} source=${V}`),K)C(this.chatId,`⚠️ ${A}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("turn_started",({retry:X})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)G(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),X){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let V=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!V){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=V?{...V}:null,this.currentTurnUsageBaselineKnown=!0}),H("token_usage",({totalUsage:X})=>{if(this.persistResumableSessionId(),X)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(X)=>{this.handleTurnPlanUpdated(X)}),H("plan_delta",(X)=>{this.handlePlanDelta(X)}),H("context_compacted",(X)=>{this.handleContextCompacted(X)}),H("rate_limits_updated",(X)=>{if($.provider==="codex")eJ(X)}),H("thread_goal_updated",(X)=>{this.handleThreadGoalUpdated(X)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:X,parentToolUseId:V})=>{if(V)return;this.appendAssistant(X)}),H("assistant_block_stop",({parentToolUseId:X})=>{if(X)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:X,name:V,input:z,parentToolUseId:A})=>{if(A&&this.bgTaskOwns(A)){this.applyBgStore(m9({active:this.backgroundTasks,pending:this.pendingBgTasks},A,X,V,z)),this.onBackgroundTaskChanged();return}if(kY(this,X,V,z),!A)this.onMainThreadAdvance();if(!A&&(V==="Task"||V==="Agent"))this.lastMainTaskToolUseId=X}),H("tool_result",({tool_use_id:X,content:V,is_error:z,parentToolUseId:A})=>{if(A&&this.bgTaskOwns(A)){this.applyBgStore(p9({active:this.backgroundTasks,pending:this.pendingBgTasks},A,X,V,z)),this.onBackgroundTaskChanged();return}SY(this,X,V,z)}),H("can_use_tool",(X)=>{vY(this,X)}),H("hook_callback",(X)=>{this.proc?.sendHookResponse(X.request_id,{})}),H("result",(X)=>{let V=this.persistResumableSessionId(),z=V?null:this.consumePendingConversationMaterialization(),A=[V,z].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",b=this.proc?.lastResult.is_error===!0;G(`session "${this.sessionName}": SDK result after user stop subtype=${O} isError=${b} — ignored`),this.status="idle";return}let K=X?.is_error!==!0?this.recordTurnAnchor(X?.checkpoint):null;if(X?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let B=this.pendingMidTurnMsgs.length>0,q=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",R=typeof X?.error==="string"&&X.error.trim()?X.error.trim():L,D,U=!1,P=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),j=[A,K].filter(Boolean).join(";")||null;if(j)D=`⚠️ ${j}`,U=!0;else if(B)D=q?`⚠️ ${P} ${R},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(q)D=`⚠️ ${P} ${R}`,U=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=D,this.openingTurnOwner.terminalForcePush=U;if(j&&!this.currentTurn&&!this.openingTurn)C(this.chatId,`⚠️ ${j}`);if(G(`session "${this.sessionName}": SDK result subtype=${L} isError=${q} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${U}`),this.closeTurnCard(D,{forcePush:U,hasFreshResult:!0}).catch((O)=>{G(`session "${this.sessionName}": result card close failed: ${F(O)}`)}),this.status="idle",B)this.drainMidTurnAndOpen().catch((O)=>{G(`session "${this.sessionName}": mid-turn drain failed: ${F(O)}`)})}),H("bg_task_started",(X)=>{let V=X.tool_use_id??this.lastMainTaskToolUseId??void 0;G(`session "${this.sessionName}": bg_task_started task=${X.task_id} type=${X.task_type??"-"} subagent=${X.subagent_type??"-"} toolUseId=${V?.slice(0,8)??"-"} desc=${(X.description??"").slice(0,40)}`),this.applyBgStore(v9(this.bgStore(),{...X,tool_use_id:V})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(X)=>{this.applyBgStore(h9(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(g9(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(X)=>{if(G(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore(c9(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(u9(this.bgStore(),X.thread_id,X.item_id,X.tool,X.phase,X.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:X,signal:V,expected:z})=>{if(G(`session "${this.sessionName}": ${$.provider} exited code=${X} signal=${V} expected=${z}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),R=this.persistResumableSessionId(!1,$,!1),D=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${F(L)}`:null,R].filter(Boolean).join(";");if(D)C(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${D}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}G(`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)=>{G(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${F(L)}`)});let A=this.backendLabel($.provider),K=`code=${X??"null"}, signal=${V??"null"}`,B=z?`\uD83D\uDED1 ${A} 已退出`:`⚠️ ${A} 异常退出 (${K})`;if(this.currentTurn)this.closeTurnCard(B).catch((L)=>{G(`session "${this.sessionName}": process-exit current main-card close failed: ${F(L)}`)});let q=this.waitForTurnCloses().catch((L)=>{G(`session "${this.sessionName}": process-exit main-card close failed: ${F(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([q,this.resetBackgroundTasks()]);for(let R of L)if(R.status==="rejected")G(`session "${this.sessionName}": process-exit terminal cleanup failed: ${F(R.reason)}`);if(!z)await N(this.chatId,`⚠️ ${A} 异常退出 (${K})。回复任意消息将重新启动。`)}).catch((L)=>{G(`session "${this.sessionName}": process-exit cleanup rejected: ${F(L)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?F9(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=U9(Z),Y=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Q=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Y,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Y,durationMs:Q}}currentContextTokens($=this.proc){if($?.provider==="claude")return $.lastContextTokens??null;let Z=$?.lastUsage;return I4(Z)}contextLimitForDisplay($=this.proc){return c4($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;if(!await this.waitForTurnOpenSlot($,Z))return;if(this.currentTurn||this.openingTurn||this.pendingMidTurnMsgs.length===0)return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){G(`session "${this.sessionName}": mid-turn open ownership conflict: ${F(Q)}`);return}let Y=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let V of Y)if(this.pendingTurnInputs.push(V.text),V.msgId){let z=this.pendingReactionIds.get(V.msgId)??"";this.currentBatchReactionIds.set(V.msgId,z),this.pendingReactionIds.delete(V.msgId)}let Q=Y.map((V)=>V.wireText).join(`
189
-
190
- `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,X=await this.openTurnCard(J,H,"user_message");if(!X||this.currentTurn!==X){for(let V of Y){if(!V.msgId)continue;let z=this.currentBatchReactionIds.get(V.msgId);if(this.currentBatchReactionIds.delete(V.msgId),z)P$(V.msgId,z)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let V of Y){if(!V.msgId)continue;let z=this.currentBatchReactionIds.get(V.msgId);if(this.currentBatchReactionIds.delete(V.msgId),z)P$(V.msgId,z)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(V){G(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${V}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await C(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${F(V)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Y=J?await D$($,M.footer,this.footerElement(Z)):!0;A$($);let Q=await K$($,z0({suffix:Z}));if(Y&&Q){await C$($);return}let W=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;G(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${W}`),await C(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${W})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{G(`session "${this.sessionName}": background rebuild after turn-open failure failed: ${F($)}`)})}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&w0(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(L){G(`session "${this.sessionName}": background migrate failed (non-blocking): ${L}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,W=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=W[0]?.slice(0,80)??this.lastTurnUserPreview,G(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${W.length}`);let H=this.runtimeModelSelection(),X=this.withModel(Y.initialFooter??"Waiting...(0s)",H),V=l4({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort,kind:J,userInputs:W,initialFooter:X,directStart:Y.directStart}),z=await i(this.chatId,V);if(!z){if(!this.ownsTurnOpen($))return null;if(G(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await C(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return this.rebuildBackgroundAfterTurnOpenFailure(),null}let A;try{A=await o$(z)}catch(L){if(G(`session "${this.sessionName}": id_convert failed: ${L}`),J==="user_message"&&this.ownsTurnOpen($))await C(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let K=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(W.length>0?1:0)+1;if(!this.ownsTurnOpen($))return u$(A,K),await this.terminalizeSupersededCard(A,"⚠️ 会话已切换,本卡已作废",!0),null;let B={cardId:A,...H,messageId:z,userOpenId:Z,trigger:J,toolCount:0,toolByUseId:new Map,planSteps:[],planExplanation:null,planUpdateCount:0,goalUpdateCount:0,contextCompactCount:0,contextCompactionPending:new Map,contextCompactionCompleted:new Set,contextCompactionCompleting:new Set,contextCompactionEndOnly:new Map,lastContextCompactionCompletedAt:0,lastContextCompactionWasAnonymous:!1,toolBatches:new Map,openBatchI:null,taskCreateI:null,taskUpdateI:null,taskBoardResetThisTurn:!1,taskLiveInserted:!1,planLiveInserted:!1,assistantSegmentCount:0,currentAssistantSegmentId:null,currentAssistantText:"",segmentTexts:new Map,startedAt:Date.now(),footerStatusHandle:null,footerStatusStartedAt:0,footerStatusLabel:null,rotating:null,rotateCount:0,failureRotateCount:0,cardCapacityFailures:new Map,cardWriteFailureNotices:new Set,cardRotationFailed:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(u$(A,K,(L,R)=>{this.onCardWriteFailure(B,A,L,R)}),this.currentTurn=B,Y.startThinking!==!1)this.startThinkingFooter(B);if($.pendingCompactions.length>0){let L=$.pendingCompactions.splice(0);G(`session "${this.sessionName}": replay ${L.length} context compaction event(s) buffered during card open`);for(let R of L)this.handleContextCompacted(R)}let q=this.takeOrphanAssistantText();if(q)this.appendAssistant(q),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((L)=>{G(`session "${this.sessionName}": background rebuild failed: ${F(L)}`)})}return B}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&I8($.cardId)<g_)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){G(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){G(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Q.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Q.rotating)return;if(Q.cardRotationFailed)return;if(!g8(J,Y)){let H=Y?.operation??"unknown operation",X=Y?.elementId?` element=${Y.elementId}`:"";G(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${X} code=${J??"n/a"} — not rotating`);let V=`${Z}:${H}:${Y?.elementId??""}:${J??"MISS"}`;if(!Q.cardWriteFailureNotices.has(V))Q.cardWriteFailureNotices.add(V),C(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H}${X})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let W=Y?.capacityFingerprint;if(W){let H=Q.cardCapacityFailures.get(W);if(H!==void 0){if(G(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Y.operation} element=${Y.elementId??"MISS"} code=${J??"MISS"}`),!H)Q.cardCapacityFailures.set(W,!0),C(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(W,!1)}G(`session "${this.sessionName}": confirmed card capacity limit (${J}) on card=${Q.cardId.slice(0,8)}… — rotating to fresh card`),Q.failureRotateCount++,this.startMidTurnRotate(Q)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Y}=$,Q={value:null},W=(H,X)=>{if(!Q.value)Q.value={code:H,failure:X}};$.rotating=(async()=>{try{G(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${I8(Z)}`);let H=l4({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort,kind:"card_full",userInputs:[]}),X=await i(this.chatId,H);if(!X){if(G(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await C(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let V;try{V=await o$(X)}catch(R){if(G(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${R}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await C(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}u$(V,2,(R,D)=>{if($.rotating){W(R,D);return}this.onCardWriteFailure($,V,R,D)});let z=$.assistantWriteInflight?.get(Z);if(z?.size)await Promise.allSettled([...z]);this.stopFooterStatus($),$.cardId=V,$.cardRotationFailed=!1,$.messageId=X,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let A=$.currentAssistantSegmentId,K=$.currentAssistantText??"",B=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,A&&K){let R=M.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=R,$.currentAssistantText=K,$.segmentTexts.set(R,K)}if(K)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)X$($.cardId,s0(this.taskBoard),{type:"insert_before",targetElementId:M.footer});if($.planLiveInserted)X$($.cardId,U2($.planSteps,$.planExplanation,M.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?M.taskBoardLive:M.footer});for(let R of $.contextCompactionPending.values()){if(R.cardId!==Z)continue;R.cardId=V,R.created=!1,R.createFailure=void 0;let D=M.contextCompact(R.i);R.createPromise=h4(V,F2(R.i,R.notice,D),{type:"insert_before",targetElementId:_$($)}).then((U)=>{if(R.cardId===V)R.created=U.landed,R.createFailure=U.failure;return U.landed})}for(let[R,D]of B){if(A&&K&&R===A)continue;if(!y1(Z,R))continue;let U=$.assistantSegmentCount++,P=M.assistant(U);$.segmentTexts.set(P,D),await this.addCompletedAssistantSegment($,P,D)}l7(this,Z,V,J,Y,$),await x$(Z),l7(this,Z,V,J,Y,$);let q=new Set([M.taskBoardLive,M.planLive,...[...$.contextCompactionPending.values()].map((R)=>M.contextCompact(R.i))]);if(A)q.add(A);for(let R of J.values())if(R.output==null)q.add(M.tool(R.i));if(g3(Z).some((R)=>!q.has(R)))$.cardCapacityFailures.clear();await x$(V);try{let R=$.mathRenderInflight?.get(Z);if(R?.size)await Promise.allSettled([...R]);await x$(Z);let D=$.mathRendered?.get(Z);for(let[O,b]of B){if(A&&K&&O===A)continue;if(y1(Z,O))continue;if(D?.has(O))continue;await n(Z,O,this.completedAssistantElement(O,b))}let U=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",P=await D$(Z,M.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${U}`)),{notifyCardFailure:!1});A$(Z);let j=await K$(Z,z0({suffix:"\uD83D\uDCE8 转下一张"}));if(P&&j)await C$(Z);else G(`session "${this.sessionName}": rotate old-card terminal MISS footer=${P} settings=${j}`),await C(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${P?"ok":"MISS"}, settings=${j?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(R){G(`session "${this.sessionName}": mid-turn rotate close-old failed: ${R}`)}G(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${V.slice(0,8)}…`)}finally{$.rotating=null;let H=Q.value;if(H&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,H.code,H.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=M.planUpdate($.planUpdateCount++);X$(Z,l8($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:_$($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=M.goalUpdate(Z.goalUpdateCount++);X$(Z.cardId,i8($,J),{type:"insert_before",targetElementId:_$(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=M.goalUpdate($.goalUpdateCount++);X$($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
191
-
192
- 已清除`},{type:"insert_before",targetElementId:_$($)})}handleContextCompacted($){let Z=KW($);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;G(`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<u6){G(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((P)=>P.startsWith("turn:")),W=Y??Q,H=W?this.contextCompactionReceipts.get(W):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let P=this.contextCompactionReceipts.get(Q);if(!P?.hasItemAlias&&P?.completed&&Date.now()-P.completedAt<u6||!P?.hasItemAlias&&P?.completionKey&&J?.contextCompactionCompleting.has(P.completionKey))W=Q,H=P,P.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,P)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),G(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");G(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(W&&H?.completed){G(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${W}`);return}let X=this.contextCompactionOwnerId(J);if(W&&H&&H.ownerId!==X){this.rememberContextCompactionReceipt(Z,null,!0),G(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${W} (turn owner changed)`);return}if(W&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){G(`session "${this.sessionName}": context compaction alias already writing receipt=${W}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){G(`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<u6){G(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let P=C_($);if(J.contextCompactionPending.has(P)||J.contextCompactionCompleted.has(P)){G(`session "${this.sessionName}": duplicate context compaction start ignored key=${P}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,X,!1);let j=J.contextCompactCount++,O=J.cardId,b=M.contextCompact(j),x={i:j,cardId:O,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};x.createPromise=h4(O,F2(j,$,b),{type:"insert_before",targetElementId:_$(J)}).then((m)=>{if(x.cardId===O)x.created=m.landed,x.createFailure=m.failure;return m.landed}),J.contextCompactionPending.set(P,x),G(`session "${this.sessionName}": context compaction start #${j+1} key=${P}`),H0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){G(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<u6){G(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let V=$.itemId||$.turnId;if(V&&J.contextCompactionCompleted.has(V)){G(`session "${this.sessionName}": duplicate context compaction completion ignored key=${V}`);return}let z=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:b_(J),A=z?J.contextCompactionPending.get(z):void 0,K=z??V??"__anonymous__";if(J.contextCompactionCompleting.has(K)){G(`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 B=f_(A?.notice,$),q=J.contextCompactionEndOnly.get(K),L=A?.i??q??J.contextCompactCount++;if(!A&&q===void 0)J.contextCompactionEndOnly.set(K,L);J.contextCompactionCompleting.add(K);let R=[...new Set([...KW(A?.notice??{}),...Z])];if(R.length>0)this.rememberContextCompactionReceipt(R,X,!1,K);let D=M.contextCompact(L),U=F2(L,B,D);G(`session "${this.sessionName}": context compaction completion write #${L+1} key=${K}`),(async()=>{let P=!1;if(!A)while(!0){let j=J.cardId;if(P=await D0(j,U,{type:"insert_before",targetElementId:_$(J)}),P)break;let O=J.rotating;if(O){await O;continue}if(J.cardId!==j)continue;break}else while(!0){let j=A.cardId;if(await A.createPromise,A.cardId!==j)continue;if(A.created)P=await D$(j,D,U);else{if(h3(A.createFailure?.code,A.createFailure))I3(j,D),P=await D$(j,D,U,{notifyCardFailure:!1});if(!P)P=await D0(j,U,{type:"insert_before",targetElementId:_$(J)})}if(A.cardId!==j)continue;if(P){A.created=!0;break}let O=J.rotating;if(O){await O;continue}if(A.cardId!==j)continue;break}if(J.contextCompactionCompleting.delete(K),!P){G(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${K}`);return}if(z&&J.contextCompactionPending.get(z)===A)J.contextCompactionPending.delete(z);if(J.contextCompactionEndOnly.delete(K),K!=="__anonymous__")J.contextCompactionCompleted.add(K);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=K==="__anonymous__",R.length>0){let j=[...this.contextCompactionReceipts.entries()].filter(([,O])=>O.completionKey===K).map(([O])=>O);this.rememberContextCompactionReceipt([...new Set([...R,...j])],null,!0)}G(`session "${this.sessionName}": context compaction completed #${L+1} key=${K}`)})().catch((P)=>{J.contextCompactionCompleting.delete(K),G(`session "${this.sessionName}": context compaction completion transaction failed: ${F(P)}`)}),H0(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Y){let Q={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Y?{}:{completionKey:Y},hasItemAlias:$.some((W)=>W.startsWith("item:"))};for(let W of $)this.contextCompactionReceipts.delete(W),this.contextCompactionReceipts.set(W,Q);while(this.contextCompactionReceipts.size>I_){let W;for(let H of this.contextCompactionReceipts.values()){if(H.completed){W=H;break}W??=H}if(!W)break;for(let[H,X]of this.contextCompactionReceipts)if(X===W)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){G(`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))G(`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?M.taskBoardLive:M.footer;Z.planLiveInserted=!0,X$(Z.cardId,U2(Z.planSteps,Z.planExplanation,M.planLive),{type:"insert_before",targetElementId:J})}else n(Z.cardId,M.planLive,U2(Z.planSteps,Z.planExplanation,M.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){G(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)G(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){G(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")G(`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&&p4(Z)===p4(J))return;let Y=this.currentTurn;if(Y){if(this.startWorkingFooter(Y),Y.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Y.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let W=Z.assistantSegmentCount++,H=M.assistant(W);Z.currentAssistantSegmentId=H,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Q=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);H0(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
193
-
194
- `).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;G(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),N(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
195
-
196
- ${J}`)}completedAssistantElement($,Z){if(p7(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Y)=>Y.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Y.text).trim()||" "}:{...Y.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Y){let Q=await EY(Y);if(!await D$(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){G(`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),G(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=_$($),W=(async()=>{if(!await D0(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return G(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(p7(J)){let X=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((V)=>G(`session "${this.sessionName}": math render ${Z} failed: ${V}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(X),X.finally(()=>$.mathRenderInflight?.get(Y)?.delete(X))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(W),W.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(W)),W}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
197
-
198
- ${J}`;if(!await N(this.chatId,Y))G(`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 XY($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return s($)}sendOutboundPath($,Z){let J=O6($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!x_(J)){G(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),G(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),v8(this.chatId,J)}startFooterStatus($,Z){if($.cardRotationFailed)return;let J=$.provider==="codex"?this.proc?.turnRetry:null;if(J)Z=J.phase==="waiting"?`⏳ 模型满载 · ${J.delayMs/1000}s 后重试 #${J.attempt}`:`⏳ 模型满载 · 正在重试 #${J.attempt}`;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Y=()=>{if($.footerStatusLabel!==Z)return;let{label:W}=B0(Date.now()-$.footerStatusStartedAt,W1());this.replaceFooterContent($.cardId,this.withModel(`${Z} (${W})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:W}=B0(Date.now()-$.footerStatusStartedAt,W1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(W)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,w_)}startWritingFooter($){this.startFooterStatus($,v_)}startWorkingFooter($){this.startFooterStatus($,h_)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Y,Q){if(J&&(!Y||!Y.enabled||Y.agent!==$))return"";if(Y?.agent===$&&Y.enabled&&$==="claude"){let H=await Y.readUsage(),X=H.windows.find((z)=>z.kind==="fiveHour"),V=H.windows.find((z)=>z.kind==="weekly");if(X||V)return this.fmtDualWindowSuffix(X??null,V??null);return H.state==="ok"&&H.planLabel?` | ${H.planLabel}`:""}if($==="codex"){let H=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,V=(H?await JY(()=>H.readRateLimits()):null)??Q;return V?.state==="ok"?this.fmtDualWindowSuffix(V.fiveHour??null,V.weekly??null):""}let W=await v7();return W.state==="ok"?this.fmtDualWindowSuffix(W.fiveHour??null,W.weekly??null):""}fmtDualWindowSuffix($,Z){let J=(H)=>H.resetsAt&&H.resetsAt.getTime()>Date.now()?V0(H.resetsAt):"",Y=(H)=>{if(H?.percent==null)return null;let X=J(H);return X?`${X}·${Math.round(H.percent)}%`:`${Math.round(H.percent)}%`},Q=Y($),W=Y(Z);if(Q&&W)return` | ${Q}·[${W}]`;if(Q)return` | ${Q}`;if(W)return` | [${W}]`;return""}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Y)=>Y.status==="rejected").map((Y)=>Y.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(F).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)P$(Z,J)}closeTurnCard($,Z={}){let J=this.currentTurn;if(!J)return this.waitForTurnCloses();if(!$&&J.cardRotationFailed)this.maybeMidTurnRotate();this.currentTurn=null,this.stopFooterStatus(J);let Y=this.proc,Q={turn:J,proc:Y,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Y),contextLimit:this.contextLimitForDisplay(Y),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:this.currentTokenSource(),codexUsage:ZY(),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let W=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(W),W.then(()=>{this.turnCloseInflight.delete(W)},()=>{this.turnCloseInflight.delete(W)}),W}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;this.stopFooterStatus(Y);let Q=((Date.now()-Y.startedAt)/1000).toFixed(1),W=Y.cardId,H=Y.segmentTexts;await x$(W);let X=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:j,currentAssistantText:O}=Y;if(!await this.addCompletedAssistantSegment(Y,j,O))X.set(j,O);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let V=Y.assistantWriteInflight?.get(W);if(V?.size)await Promise.allSettled([...V]);let z=Y.mathRenderInflight?.get(W);if(z?.size)await Promise.allSettled([...z]);let A=Y.mathRendered?.get(W);for(let[j,O]of H){if(y1(W,j)){X.set(j,O);continue}if(A?.has(j))continue;await n(W,j,this.completedAssistantElement(j,O))}if(Y.cardRotationFailed)for(let[j,O]of H)X.set(j,O);let K=Z?Z:"✅",B=[`${K} ⏱ ${Q}s`];if(J.hasFreshResult){let{contextTokens:j,contextLimit:O}=$,b=Y.provider==="claude",x=u8(j,O,b?0:void 0);if(x)B.push(`\uD83E\uDDE0 ${x}`);let m=$.lastTurnDelta?.costUsd??0;if(m>0)B.push(`\uD83D\uDCB0 $${m.toFixed(3)}`)}if(Y.contextCompactCount>0)B.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)B.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let q=this.modelLine(Y);if(q)B.push(q);let L=B.join(" | "),R=J.hasFreshResult?p8($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",D=R?`${L}
199
- ${R}`:L,U=await D$(W,M.footer,this.footerElement(D));A$(W);let P=await K$(W,z0({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(U&&P)await C$(W);else{let j=`footer=${U?"ok":"MISS"}, settings=${P?"ok":"MISS"}`;G(`session "${this.sessionName}": terminal card transaction incomplete card=${W.slice(0,12)} ${j}`),await C(this.chatId,`⚠️ 对话卡片终态写入失败 (${j})。本轮已结束: ${K}`)}for(let j of X.values())await this.sendAssistantTextFallback(j,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)l0(Y.messageId,[Y.userOpenId])}}});function w$($){return{card:{type:"raw",data:$}}}import{readFileSync as c_}from"node:fs";function DW($){return R5.has($)}function jW($){R5.add($)}function MW($){R5.delete($)}function m2(){try{let $={};for(let[Z,J]of t$)$[Z]=J;H$(p6,$)}catch($){throw G(`notify-callbacks: save failed (${p6}): ${$}`),$}}function FW(){let $;try{$=c_(p6,"utf8")}catch{return}try{let Z=JSON.parse($),J=Date.now()-PW,Y=0;for(let Q of Object.values(Z)){if(!Q||typeof Q!=="object")continue;if(typeof Q.notifyId!=="string"||typeof Q.callbackUrl!=="string")continue;if(typeof Q.createdAt!=="number"||Q.createdAt<J){Y++;continue}t$.set(Q.notifyId,Q)}if(G(`notify-callbacks: loaded ${t$.size} registration(s)${Y?`, dropped ${Y} stale`:""}`),Y>0)m2()}catch(Z){G(`notify-callbacks: load failed (${p6}): ${Z}`)}}function UW($){let Z=Date.now();if(Z-LW>=m_)p_(Z),LW=Z;t$.set($.notifyId,$),m2()}function l6($){return t$.get($)}function L5($,Z,J){let Y=t$.get($);if(!Y)throw Error(`notify registration not found: ${$}`);let Q={resolvedAt:Y.resolvedAt,resolvedBy:Y.resolvedBy,unknownAt:Y.unknownAt,unknownBy:Y.unknownBy,unknownReason:Y.unknownReason};Y.resolvedAt=Date.now(),Y.resolvedBy={buttonId:Z,openId:J},delete Y.unknownAt,delete Y.unknownBy,delete Y.unknownReason;try{m2()}catch(W){if(Q.resolvedAt===void 0)delete Y.resolvedAt;else Y.resolvedAt=Q.resolvedAt;if(Q.resolvedBy===void 0)delete Y.resolvedBy;else Y.resolvedBy=Q.resolvedBy;if(Q.unknownAt===void 0)delete Y.unknownAt;else Y.unknownAt=Q.unknownAt;if(Q.unknownBy===void 0)delete Y.unknownBy;else Y.unknownBy=Q.unknownBy;if(Q.unknownReason===void 0)delete Y.unknownReason;else Y.unknownReason=Q.unknownReason;throw W}}function u_($,Z,J,Y){let Q=t$.get($);if(!Q)throw Error(`notify registration not found: ${$}`);delete Q.resolvedAt,delete Q.resolvedBy,Q.unknownAt=Date.now(),Q.unknownBy={buttonId:Z,openId:J},Q.unknownReason=Y,m2()}function OW($,Z,J){try{return L5($,Z,J),{state:"complete"}}catch(Y){let W=`resolved tombstone persistence failed: ${Y instanceof Error?Y.message:String(Y)}`;try{u_($,Z,J,W)}catch(H){let X=H instanceof Error?H.message:String(H);W+=`; unknown tombstone persistence also failed: ${X}`;let V=t$.get($);if(V)V.unknownReason=W}return{state:"unknown",detail:W}}}function p_($=Date.now()){let Z=$-PW,J=0;for(let[Y,Q]of t$)if(typeof Q.createdAt!=="number"||Q.createdAt<Z)t$.delete(Y),J++;if(J>0)m2();return J}async function EW($,Z,J){let Y={notify_id:$.notifyId,message_id:$.messageId,chat_id:$.chatId,project:$.project,button:{id:Z.id,text:Z.text,type:Z.type},operator:{open_id:J},timestamp:Math.floor(Date.now()/1000)},Q=new AbortController,W=setTimeout(()=>Q.abort(),RW);try{let H=await fetch($.callbackUrl,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(Y),signal:Q.signal});if(H.status>=200&&H.status<300){let V;try{let z=(await H.text()).trim();if(z.startsWith("{")){let A=JSON.parse(z),K=typeof A?.text==="string"?A.text:typeof A?.reply==="string"?A.reply:typeof A?.message==="string"?A.message:"";if(K.trim())V=K.trim().slice(0,500)}else if(z)V=z.slice(0,500)}catch{}return{ok:!0,detail:`${H.status}`,reply:V}}let X="";try{X=(await H.text()).slice(0,120)}catch{}return{ok:!1,detail:`HTTP ${H.status}${X?` ${X}`:""}`}}catch(H){if(H?.name==="AbortError")return{ok:!1,detail:`回调超时 ${RW}ms(本地服务未在窗口内 2xx)`};return{ok:!1,detail:`回调失败: ${String(H?.message??H).slice(0,160)}`}}finally{clearTimeout(W)}}function TW($){let Z=!!$.resolvedAt,J=!!$.unknownAt,Y=$.resolvedBy?.buttonId??$.unknownBy?.buttonId,Q=Y?$.buttons.find((W)=>W.id===Y):void 0;return{notify_id:$.notifyId,project:$.project,message_id:$.messageId,resolved:Z,unknown:J,...Z?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y},resolved_at:$.resolvedAt,resolved_by:$.resolvedBy?.openId??null}:{},...J?{button:Q?{id:Q.id,text:Q.text,type:Q.type}:{id:Y},unknown_at:$.unknownAt,unknown_by:$.unknownBy?.openId??null,unknown_reason:$.unknownReason}:{}}}var PW=604800000,RW=2500,t$,LW,m_=86400000,R5,p6;var P5=S(()=>{g();R$();g$();t$=new Map,LW=Date.now(),R5=new Set;p6=l5});import{createServer as l_}from"node:http";import{randomUUID as i_}from"node:crypto";function SW($){let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!($.buttons?.length&&$.notifyId),Q=new Date,W=`${String(Q.getHours()).padStart(2,"0")}:${String(Q.getMinutes()).padStart(2,"0")}`,H=[];for(let X of $.images??[])if(X.key)H.push({tag:"img",img_key:X.key,alt:{tag:"plain_text",content:"screenshot"}});else H.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${X.src}</font>`});if(H.push({tag:"markdown",content:C9($.text??"")||"_(空消息)_"}),$.resolution){let X=$.resolution,V;if(X.status==="processing")V=`<font color='blue'>⏳ 已选择:${X.text} · 推送中…</font>`;else if(X.status==="failed")V=`<font color='red'>⚠️ 已选:${X.text} · 回调失败:${X.detail??"未知"} · ${W}</font>`;else if(X.status==="delivered")V=`<font color='green'>✅ 已选择:${X.text} · 反馈已送达 · ${W}</font>`;else if(X.status==="unknown")V=`<font color='red'>⚠️ 已选择:${X.text} · 外部回调已成功,但本地确认状态未知,禁止自动重试 · ${W}</font>`;else V=`<font color='green'>✅ 已选择:${X.text} · ${W}</font>`;if(H.push({tag:"markdown",content:V}),X.status==="delivered"&&X.reply)H.push({tag:"markdown",content:s(X.reply)})}if(Y&&(!$.resolution||$.resolution.status==="failed"))H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((X)=>({tag:"button",text:{tag:"plain_text",content:X.text},type:X.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:X.id}}]}))}]});return H.push({tag:"hr"}),H.push({tag:"markdown",content:`<font color='grey'>via notify · ${W}</font>`}),{schema:"2.0",config:Y?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:H}}}function o_($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Y of $){if(!Y||typeof Y!=="object")return{error:"each button must be an object"};let Q=String(Y.id??"").trim(),W=String(Y.text??"").trim();if(!a_.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!W)return{error:`button "${Q}" missing text`};if(W.length>NW)return{error:`button "${Q}" text > ${NW} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=n_.has(H)?H:"default";J.push({id:Q,text:W,type:X})}return{buttons:J}}function r_($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Y=J.hostname.replace(/^\[|]$/g,"");if(Y!=="127.0.0.1"&&Y!=="localhost"&&Y!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function yW($){try{let Z=l_((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:kW(J,Y)):kW(J,Y)).catch((H)=>{if(G(`notify: handler crash: ${H?.message??H}`),!Y.headersSent)Y.statusCode=500,Y.setHeader("content-type","text/plain; charset=utf-8"),Y.end("internal error");else try{Y.end()}catch{}})});Z.on("error",(J)=>{G(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{G(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){G(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function kW($,Z){let J=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Y=(T,k)=>{Z.statusCode=T,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(k)},Q=(T,k)=>{Z.statusCode=T,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(k))};if($.method==="GET"&&J.pathname==="/")return Y(200,`lodestar notify
200
- `+`POST /notify body={project,text,title?,level?,images?,buttons?,callback?} push card to group
201
- `+`GET /notify/result/<notify_id>poll a button card's resolution (pull mode, no callback server)
178
+ ${G}`)}return{slug:Y,chatName:W,branch:Q,worktreePath:V,removedWorktree:!1}}function E5($){if(!H1($))throw Error(`project directory does not exist: ${$}`);let Z=B0($,["rev-parse","--show-toplevel"]).trim();if(U5(Z)!==U5($))throw Error(`${$} is not the git repository root (${Z})`)}function VW($,Z){let J=B0($,["rev-parse","--abbrev-ref","HEAD"]).trim();if(J!==Z)throw Error(`${$} is on ${J}, expected ${Z}`)}function DK($,Z,J){let Y=MK($);if(!Y?.startsWith(n1))return null;let Q=Y.slice(n1.length);if(!X1(Q))throw Error(`invalid worktree branch "${Y}"`);let W=o1(Z,J,Q);if(s9($)!==s9(W))return null;let H=UK($,FK(Q));return H?{path:H,slug:Q}:null}function MK($){if(!H1($))return null;try{return B0($,["branch","--show-current"]).trim()||null}catch(Z){if(EK(Z))return null;throw Z}}function FK($){return $.split("-",1)[0]??$}function UK($,Z){let J=`agents.${Z}.md`,Y=qK($).filter((Q)=>Q.toLowerCase()===J).sort();if(Y.length>1)throw Error(`multiple worktree instruction files match ${J}: ${Y.join(", ")}`);return Y[0]?ZW($,Y[0]):null}function OK($,Z){try{return B0($,["show-ref","--verify","--quiet",`refs/heads/${Z}`]),!0}catch{return!1}}function zW($,Z,J){let Y=B0($,["rev-parse",Z]).trim(),Q=B0($,["rev-parse","HEAD"]).trim();if(Y===Q)return J?"active":"merged";if($W($,Z,"HEAD"))return"merged";if($W($,"HEAD",Z))return"active";return"stale"}function $W($,Z,J){try{return B0($,["merge-base","--is-ancestor",Z,J]),!0}catch{return!1}}function T5($){let Z=new Map,J=B0($,["worktree","list","--porcelain"]),Y="";for(let Q of J.split(`
179
+ `)){if(Q.startsWith("worktree ")){Y=Q.slice(9);continue}if(Q.startsWith("branch refs/heads/")&&Y)Z.set(Q.slice(18),Y)}return Z}function B0($,Z){try{return BK("git",Z,{cwd:$,encoding:"utf8",stdio:["ignore","pipe","pipe"]})}catch(J){throw Error(N5(J))}}function N5($){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 EK($){return/not a git repository/i.test(N5($))}var n1="work/",RK,t9;var GW=N(()=>{RK=/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/,t9=new Map});function y$($){return JW(o0($.sessionName)??$.sessionName)}function r1($){return u4(y$($))}function _W($){let Z=o0($.sessionName)??$.sessionName,J=y$($),Y=u4(J);if(J===Z)return Y;let Q=Z.slice(J.length+1,-1);return o1(Y,J,Q)}function KW($,Z=$.currentProvider()){let J=Z==="claude"?sQ:tQ,Y=t2($);return Y?`${J}
180
+ ${Y}`:J}function BW($,Z){return t2($)??""}function k5($){return t2($)?"已载入wt特殊约定":null}function qW($,Z){let J=k5($);return J?`${Z}
181
+ ${J}`:Z}function t2($){let Z=y$($),J=QW($.workDir,r1($),Z);if(!J)return null;return[`你要把下面这份额外的工作树约定视为和AGENTS.md一样重要。来源文件:${J.path}`,"",`# Additional AGENTS.md instructions for ${$.workDir}`,"","<INSTRUCTIONS>",J.content,"</INSTRUCTIONS>"].join(`
182
+ `)}async function LW($,Z,J){if(!Z){await S5($);return}let Y=X1(Z);if(!Y){await T($.chatId,"❌ 名称无效。用英文/数字/._-,最长 63。");return}if(!J){await T($.chatId,"❌ 找不到发起人,不能拉群。");return}let Q=y$($),W=r1($);try{await e9(W,async()=>{let H;try{H=HW(W,Q,Y)}catch(X){await T($.chatId,`❌ wt 失败: ${F(X)}`);return}try{let X=await l7(H.chatName,J),V=X.created?"已创建":X.joined?"已加入":"已在群内";if(!await i($.chatId,c2({slug:Y,branch:H.branch,status:V})))await C($.chatId,`❌ wt 卡片失败: ${Y}`);if(!await i(X.chatId,c2({slug:Y,branch:H.branch,status:"就绪",body:"开始吧。"})))await C(X.chatId,`❌ wt 卡片失败: ${Y}`)}catch(X){await T($.chatId,`❌ wt 已建,拉群失败: ${F(X)}`)}})}catch(H){await T($.chatId,`❌ wt 失败: ${F(H)}`)}}async function PW($,Z){let J=y$($),Y=r1($);return await e9(Y,async()=>{return await NK(J,Y,Z)})}async function NK($,Z,J){let Y=WW(Z,$),Q=Y.filter((X)=>X.state==="merged"&&!X.mounted).length,W=Y.filter((X)=>X.state!=="merged"||X.mounted),H=await l4();return S8({projectName:$,projectDir:Z,hiddenMergedUnmountedCount:Q,notice:J,entries:W.map((X)=>{let V=H.get(X.chatName)??[],z=Y0.get(X.chatName),G=z&&V.includes(z)?z:V.length===1?V[0]:null;return{slug:X.slug,chatName:X.chatName,branch:X.branch,state:X.state,path:X.worktreePath??X.expectedPath,mounted:X.mounted,dirtyCount:X.dirtyCount,statusLine:X.statusLine,error:X.error,chatId:G,duplicateChatCount:V.length}})})}async function S5($){try{let Z=await PW($);if(!await i($.chatId,Z))await C($.chatId,"❌ wt 列表失败")}catch(Z){await T($.chatId,`❌ wt 列表失败: ${F(Z)}`)}}async function AW($,Z,J,Y){try{return{ok:Z,message:J,card:await PW($,{type:Y,content:J})}}catch(Q){let W=`列表刷新失败: ${F(Q)}`;return A(`session "${$.sessionName}": wt action panel refresh failed: ${F(Q)}`),{ok:!1,message:`${J}
183
+ ${W}`,card:c2({slug:"wt",branch:"work/*",status:J,body:W,template:"red"})}}}async function jW($,Z){let J=X1(Z);if(!J)return AW($,!1,"❌ 名称无效","error");let Y=y$($),Q=r1($),W;try{W=await e9(Q,async()=>{let H=a1(Y,J);if($.hasRunningPeerSession(H))return{ok:!1,message:`❌ 解散 ${J} 失败: Codex 正在运行,请先在 ${H} 群里 stop 或 kill。`,type:"error"};O5(Q,Y,J);let X=await d7(H),V=XW(Q,Y,J);return{ok:!0,message:[`✅ ${J} 已解散`,V.removedWorktree?"dir removed":"dir missing",X.disbanded?"group removed":"group missing",V.branch].join(`
184
+ `),type:"success"}})}catch(H){W={ok:!1,message:`❌ 解散 ${J} 失败: ${F(H)}`,type:"error"}}return AW($,W.ok,W.message,W.type)}var RW=N(()=>{eQ();f0();s();I();GW()});import{closeSync as SK,openSync as yK,readSync as xK,readdirSync as bK,statSync as CK}from"node:fs";import{randomUUID as x5}from"node:crypto";import{join as wK}from"node:path";function Z6($){return o0($.sessionName)??$.sessionName}function MW($){let Z=h7($,y5);return y5.add(Z),Z}function FW($){y5.delete($)}function t1($){let Z=DW.get($);if(!Z)Z=new Map,DW.set($,Z);let J=Date.now();for(let[Y,Q]of Z){let W=Q.status==="consumed"?hK:vK,H=Q.consumedAt??Q.createdAt;if(J-H>W)Z.delete(Y)}return Z}function IK($,Z){return $.provider===Z.provider&&$.tokenSourceId===Z.tokenSourceId&&$.model===Z.model&&$.effort===Z.effort}function UW($,Z,J,Y){let Q={id:x5(),mode:Z,requesterOpenId:J,provider:$.selectedProvider,sourceSessionId:$.lastSessionId,workDir:$.workDir,baseName:Z6($),routing:$.conversationRouting(),createdAt:Date.now(),status:"open",choices:Y};return t1($).set(Q.id,Q),Q}function b5($,Z,J,Y,Q){let W=t1($).get(J);if(!W||W.mode!==Z)return{error:"这张选择卡已过期,请重新发送命令"};if(!Q||W.requesterOpenId!==Q)return{error:"只有打开这张选择卡的用户可以执行;请自行发送命令重新打开"};if(W.status!=="open")return{error:"这张选择卡已执行或正在处理,请勿重复点击"};if(W.provider!==$.selectedProvider||W.workDir!==$.workDir||W.sourceSessionId!==$.lastSessionId||!IK(W.routing,$.conversationRouting()))return{error:"这张卡对应的 provider、目录或源会话已经变化,请重新发送命令"};let H=W.choices.get(Y);if(!H)return{error:"无效的选择项,这张卡可能已过期"};return W.status="processing",{panel:W,choice:H}}function $6($){$.status="consumed",$.consumedAt=Date.now()}function cK($){return{kind:"fork",source:$.source,through:$}}function mK($){return F2($.sessionName).filter((Z)=>Z.checkpoint.provider===$.selectedProvider&&Z.checkpoint.source.cwd===$.workDir)}function uK($){let Z=U2($.sessionName);if(Z===null||Z.kind==="fresh")return Z;try{return z0(Z,$.selectedProvider,$.workDir),Z}catch{return null}}function pK($){let Z=K7($),J;try{J=bK(Z)}catch(Q){if(Q?.code==="ENOENT")return[];throw Error(`读取 Claude 会话目录失败: ${Q?.message??Q}`)}let Y=[];for(let Q of J){if(!Q.endsWith(".jsonl"))continue;let W=Q.slice(0,-6);if(P4("claude",W))continue;let H=wK(Z,Q),X;try{X=CK(H).mtimeMs}catch(V){throw Error(`读取 Claude 会话元数据失败 (${Q}): ${V?.message??V}`)}Y.push({provider:"claude",sessionId:W,cwd:$,preview:iK(H),ts:X})}return Y.sort((Q,W)=>W.ts-Q.ts)}function lK($){let Z=$.slice().sort((Q,W)=>W.ts-Q.ts),J=Date.now()-fK,Y=Z.filter((Q)=>Q.ts>=J).length;return Z.slice(0,Math.min(gK,Math.max(10,Y)))}function iK($){let Z="",J=null;try{J=yK($,"r");let Q=Buffer.alloc(65536),W=xK(J,Q,0,65536,0);Z=Q.subarray(0,W).toString("utf8")}catch(Q){throw Error(`读取 Claude 会话摘要失败 (${$}): ${Q?.message??Q}`)}finally{if(J!==null)SK(J)}let Y="";for(let Q of Z.split(`
185
+ `)){let W=Q.trim();if(!W)continue;let H;try{H=JSON.parse(W)}catch{continue}if(H.type==="queue-operation"&&H.operation==="enqueue"&&typeof H.content==="string"){let X=H.content.trim();if(X)return X.slice(0,80)}if(!Y&&H.type==="user"&&H.message){let X=dK(H.message);if(X)Y=X}}return Y.slice(0,80)}function dK($){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 OW($,Z,J){if(!J){await T($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let Y=mK($),Q=uK($),W=new Map,H=[];for(let G=0;G<Y.length;G++){let _=Y[G];if(G===0&&Q===null)continue;let B=x5(),q=G===0?Q:cK(Y[G-1].checkpoint);W.set(B,{kind:Z,launch:q,branchBase:Q,seedAnchors:Y.slice(0,G),writes:Y.slice(G).flatMap((L)=>L.writes)}),H.push({choiceId:B,preview:_.preview,ts:_.ts})}H.reverse();let X=UW($,Z,J,W),V=x8({projectName:Z6($),panelId:X.id,mode:Z,entries:H}),z;try{z=await i($.chatId,V)}catch(G){throw t1($).delete(X.id),G}if(!z)t1($).delete(X.id),await C($.chatId,`❌ ${Z==="fork"?"fk":"bk"} 列表发送失败`)}function EW($,Z){return OW($,"fork",Z)}function TW($,Z){return OW($,"back",Z)}async function NW($,Z){if(!Z){await T($.chatId,"❌ 找不到发起人,无法创建安全选择卡。");return}let J;try{J=$.selectedProvider==="codex"?await $.listCodexConversations():pK($.workDir)}catch(V){await C($.chatId,`❌ 历史会话读取失败: ${V instanceof Error?V.message:V}`);return}let Y=new Map,Q=lK(J).map((V)=>{let z=x5();return Y.set(z,{kind:"resume",launch:{kind:"fork",source:{provider:V.provider,sessionId:V.sessionId,cwd:V.cwd}},sourcePreview:V.preview,sourceTs:V.ts,sourceStatus:V.status}),{choiceId:z,preview:V.preview,ts:V.ts}}),W=UW($,"resume",Z,Y),H=b8({projectName:Z6($),panelId:W.id,entries:Q}),X;try{X=await i($.chatId,H)}catch(V){throw t1($).delete(W.id),V}if(!X)t1($).delete(W.id),await C($.chatId,"❌ rs 历史列表发送失败")}async function kW($,Z){if(!Z){await T($.chatId,"❌ 找不到发起人,无法建临时群。");return}if(!$.opts.onCreateTempSession){await T($.chatId,"❌ 临时群能力未就绪(daemon 未注入回调)。");return}let J=MW(Z6($));await T($.chatId,`\uD83D\uDE80 正在创建 ${J} · ${$.backendLabel()} 新会话。它与当前群共享工作目录;当前会话不受影响。`);let Y;try{Y=await $.opts.onCreateTempSession({chatName:J,userOpenId:Z,workDir:$.workDir,routing:$.conversationRouting(),launch:{kind:"fresh"},branchBase:{kind:"fresh"},seedAnchors:[]})}finally{FW(J)}if(!Y.ok){await T($.chatId,`❌ 建临时会话失败: ${Y.error??"未知"}`);return}await T($.chatId,`✅ 已创建 ${J}。临时群不会自动删除;在该群发送 bye 可停止并解散。`)}async function SW($){if(!o0($.sessionName)){await T($.chatId,"❌ bye 只能在带 *MMDD-HHMM 后缀的临时会话群里使用。");return}if(!$.opts.onDisbandTempSession){await T($.chatId,"❌ 解散能力未就绪(daemon 未注入回调)。");return}await T($.chatId,`\uD83D\uDC4B 正在停止会话并解散 ${$.sessionName}…`);let Z=await $.opts.onDisbandTempSession($.sessionName,$.chatId);if(!Z.ok)await T($.chatId,`❌ 解散失败: ${Z.error??"未知"}`)}async function yW($,Z,J,Y){let Q=b5($,"fork",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="fork")return{ok:!1,message:"选择项类型不匹配"};if(!$.opts.onCreateTempSession)return{ok:!1,message:"临时群能力未就绪"};let X=MW(W.baseName);A(`session-temp: fork ${$.sessionName} → ${X} (${H.launch.kind})`),await T($.chatId,`\uD83D\uDD31 正在分叉到 ${X}…`);let V;try{V=await $.opts.onCreateTempSession({chatName:X,userOpenId:Y,workDir:W.workDir,routing:W.routing,launch:H.launch,branchBase:H.branchBase,seedAnchors:H.seedAnchors})}finally{FW(X)}if(!V.ok)return{ok:!1,message:`分叉失败: ${V.error??"未知"}`};return{ok:!0,message:`已分叉到 ${X};原会话和磁盘文件未回滚`}}catch(X){return{ok:!1,message:`分叉失败: ${X instanceof Error?X.message:X}`}}finally{$6(W)}}async function xW($,Z,J,Y){let Q=b5($,"back",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;try{if(H.kind!=="back")return{ok:!1,message:"选择项类型不匹配"};let X="";try{if(!await i($.chatId,C8({projectName:W.baseName,entries:H.writes})))X=";文件变更记录卡发送失败"}catch(G){X=`;文件变更记录卡发送失败: ${G instanceof Error?G.message:G}`}if(A(`session-temp: back ${$.sessionName} (${H.launch.kind}, writes=${H.writes.length})`),!await $.rollbackTo(H.launch,{anchors:H.seedAnchors,base:H.branchBase}))return{ok:!1,message:`回退失败;原会话绑定未改,请检查日志后重试${X}`};if(W.routing.provider==="claude")return{ok:!0,message:`本群已准备 Claude 新分支;发送下一条消息时生成并接入,旧会话未删除,磁盘文件未回滚${X}`};return{ok:!0,message:`本群已改接新会话${$.lastSessionId?` ${V0($.lastSessionId)}`:""};旧会话未删除,磁盘文件未回滚${X}`}}catch(X){return{ok:!1,message:`回退失败: ${X instanceof Error?X.message:X}`}}finally{$6(W)}}async function bW($,Z,J,Y){let Q=b5($,"resume",Z,J,Y);if("error"in Q)return{ok:!1,message:Q.error,replaceCard:!1};let{panel:W,choice:H}=Q;if(H.kind!=="resume")throw $6(W),Error("resume panel contained a non-resume choice");let X=H.launch.source.sessionId,V=$.lastSessionId,z=(_,B)=>({projectName:W.baseName,provider:H.launch.source.provider,selectedPreview:H.sourcePreview,selectedTs:H.sourceTs,sourceSessionId:X,...H.sourceStatus?{sourceStatus:H.sourceStatus}:{},previousSessionId:V,newSessionId:_,bindingState:B}),G=(_,B,q,L=null)=>({ok:_,message:B,resumePresentation:z(L,q)});try{if($.isRunning())return G(!1,"当前群已经启动了新进程;为避免误杀,请先停止后重新发送 rs","unchanged");if(H.sourceStatus==="active")return G(!1,"所选 Codex 会话仍在运行;请先在原位置停止后再创建完整分支","unchanged");if(A(`session-temp: history fork ${$.sessionName} ← ${H.launch.source.provider} ${X}`),!await $.rollbackTo(H.launch,{anchors:[],base:H.launch,pendingLaunch:H.launch.source.provider==="claude"?{launch:H.launch,previousSessionId:V}:null}))return G(!1,"历史分支创建失败;原会话绑定未改,请检查日志后重试","unchanged");if(H.launch.source.provider==="claude")return G(!0,"Claude 独立分支已准备;首条消息时生成并接入新会话","prepared");let B=$.lastSessionId;if(!B)return G(!1,"历史分支已启动,但后端没有返回新会话 id","unknown");if(B===X||V&&B===V)return G(!1,"后端没有返回独立的新会话 id;为避免误判,本次不标记为恢复成功","unknown",B);return G(!0,"已创建并接入独立分支;源会话未修改","changed",B)}catch(_){return G(!1,`历史分支创建失败: ${_ instanceof Error?_.message:_}`,"unknown")}finally{$6(W)}}var fK=86400000,vK=1800000,hK=3600000,gK=40,DW,y5;var CW=N(()=>{s();f0();I();y4();j4();D1();DW=new WeakMap,y5=new Set});import{existsSync as wW}from"node:fs";import{randomBytes as aK,timingSafeEqual as oK}from"node:crypto";import{isAbsolute as rK}from"node:path";function w5($,Z=new Set){if($ instanceof V2)return $;if(!$||typeof $!=="object"&&typeof $!=="function"||Z.has($))return null;if(Z.add($),$ instanceof AggregateError)for(let J of $.errors){let Y=w5(J,Z);if(Y)return Y}if($ instanceof Error&&$.cause!==void 0)return w5($.cause,Z);return null}function tK($){return $.itemId||$.turnId||"__latest__"}function fW($){let Z=[];if($.itemId)Z.push(`item:${$.itemId}`);if($.turnId)Z.push(`turn:${$.threadId??$.sessionId??"-"}:${$.turnId}`);return Z}function sK($){let Z=null;for(let J of $.contextCompactionPending.keys())Z=J;return Z}function eK($,Z){if(!$)return Z;return{...$,...Z,phase:"end"}}function V1(){return v.runtime?.live_elapsed??"bucket"}function hW($,Z){return`${$} (${L$(Date.now()-Z,V1()).label})`}var $B="Thinking...",ZB="Writing...",JB="Working...",C5=1e4,J6=120000,YB=50,QB=256,Y6=1e4,vW=250,z1;var gW=N(()=>{F1();H7();I$();U0();R7();G0();y4();o$();f0();s();I();L0();M8();x9();C9();t8();SY();uY();YQ();I9();HQ();FQ();OQ();CQ();IQ();aQ();RW();CW();D1();z1=class z1{sessionName;chatId;opts;static all=new Set;proc=null;lifecycleTail=Promise.resolve();lifecycleSequence=0;procEpoch=0;stoppingProc=null;blockedProc=null;blockedProcReason=null;agentCapability=null;procSourceRevisions=new WeakMap;currentTurn=null;contextCompactionReceipts=new Map;contextCompactionOwnerIds=new WeakMap;contextCompactionOwnerSequence=0;lastManualContextCompactionCompletedAt=0;lastManualContextCompactionWasAnonymous=!1;backgroundTasks=[];pendingBgTasks=[];backgroundCard=null;settlingBackgroundCard=!1;migratingBackgroundCard=null;backgroundRefreshTimer=null;backgroundRefreshTick=null;openingBackground=!1;openingBackgroundOwner=null;backgroundOpenSequence=0;backgroundGeneration=0;backgroundDetailAdded=new Set;backgroundDetailAdding=new Set;lastMainTaskToolUseId=null;pendingRebuildBackgroundCard=!1;bgResumePending=!1;orphanAssistantSegments=[];orphanAssistantCurrent="";bgResumeCardless=!1;pendingPermissions=new Map;pendingAsks=new Map;currentGoal=null;status="stopped";pendingUserMessageCount=0;pendingMidTurnMsgs=[];pendingTurnInputs=[];multiMsgBuffer=null;multiMsgReactions=new Map;lastUserOpenId="";pendingReactionIds=new Map;currentBatchReactionIds=new Map;initCount=0;openingTurn=!1;openingTurnOwner=null;turnOpenSequence=0;turnCloseInflight=new Set;turnCounter=0;userInterrupted=!1;lastSessionId=null;lastSessionRef=null;selectedProvider="claude";selectedModel=null;selectedEffort=null;selectedTokenSourceId=null;modelPanels=new Map;modelCustomPrompt=null;startedAt=0;cumStats={tokens:0,costUsd:0,turns:0};lastTurnDelta=null;currentTurnUsageBaseline=null;currentTurnUsageBaselineKnown=!1;lastTurnUsage=null;usageTotalsSeedUnknown=!1;resumePersistenceError=null;manualContextCompactionPending=!1;taskBoard=[];constructor($,Z,J={}){this.sessionName=$;this.chatId=Z;this.opts=J;z1.all.add(this);let Y=m7($);this.selectedProvider=Y?.provider??"claude",this.selectedModel=Y?.model??null,this.selectedEffort=Y?.effort??null,this.selectedTokenSourceId=this.deriveTokenSourceId(Y);let Q=$0(this.selectedTokenSourceId);if(Q){if(this.selectedProvider=Q.agent,Q.id==="glm"&&this.selectedModel==="claude:glm")this.selectedModel=Q.defaultModel,this.selectedEffort="max";if(Q.id==="claude-native"&&this.selectedModel&&!Q.models.some((H)=>H.model===this.selectedModel))this.selectedModel=Q.defaultModel}if(this.selectedModel)A(`session "${$}": restored selected provider=${this.selectedProvider} model=${this.selectedModel} effort=${this.selectedEffort??"unset"}`);if(this.lastSessionRef=d$($,this.selectedProvider),this.lastSessionId=this.lastSessionRef?.sessionId??null,this.lastSessionId)A(`session "${$}": restored ${this.selectedProvider} lastSessionId=${this.lastSessionId}`);let W=O2($);if(W)if(this.selectedProvider!=="claude")m0($,[],null,null),A(`session "${$}": cleared pending Claude fork after provider changed`);else{z0(W.launch,"claude",this.workDir);let H=this.lastSessionId===W.previousSessionId,X=this.lastSessionRef,V=!H&&X?.provider==="claude"&&X.cwd===this.workDir&&X.sessionId!==W.launch.source.sessionId&&X.sessionId!==W.previousSessionId;if(!H&&!V)throw Error(`pending Claude fork has inconsistent resume binding for session "${$}"`);this.pendingConversationMaterialization=W,A(`session "${$}": restored ${V?"materialized":"pending"} Claude fork source=${W.launch.source.sessionId}`)}}peerSnapshot(){return{name:this.sessionName,status:this.status,uptimeMs:this.startedAt?Date.now()-this.startedAt:void 0}}get workDir(){return _W(this)}isRunning(){return!!this.proc&&this.proc.isAlive()}shouldRevive(){return 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 b4(J==="codex"?"codex":"claude")[0]?.id??null}currentTokenSource(){return $0(this.selectedTokenSourceId)}currentProvider(){return this.selectedProvider}conversationRouting(){return{provider:this.selectedProvider,tokenSourceId:this.selectedTokenSourceId,model:this.selectedModel,effort:this.selectedEffort}}applyConversationRouting($){if(this.isRunning()||this.currentTurn||this.openingTurn)throw Error("cannot change conversation routing while the session is running");let Z=$0($.tokenSourceId);if(Z&&Z.agent!==$.provider)throw Error(`token source "${Z.id}" belongs to ${Z.agent}, not ${$.provider}`);if(this.selectedProvider!==$.provider)m0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$.provider,this.selectedTokenSourceId=$.tokenSourceId,this.selectedModel=$.model,this.selectedEffort=$.effort,this.lastSessionRef=d$(this.sessionName,$.provider),this.lastSessionId=this.lastSessionRef?.sessionId??null,c7(this.sessionName,$.provider,$.model,$.effort,$.tokenSourceId)}async listCodexConversations(){if(this.selectedProvider!=="codex")throw Error("Codex history requested for a non-Codex session");if(!k2())throw Error("Codex 未登录 ChatGPT 账号");let $=this.currentTokenSource();if(this.selectedTokenSourceId&&(!$||!$.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Z=$?.enabled?$:void 0,J=Z?(X)=>Z.spawnEnv(X):void 0,Y=new M1({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Z?.id??null,transformEnv:J}),Q=null,W=null;try{Q=await Y.listConversations()}catch(X){W=X}let H=null;try{await Y.kill(2000)}catch(X){H=X}if(W&&H)throw AggregateError([W,H],`Codex history query and cleanup failed: ${F(W)}; ${F(H)}`);if(W)throw W;if(H)throw H;return Q??[]}async resolveLegacyResumeRef($){if($.cwd!==null)return $;if($.provider!==this.selectedProvider)throw Error(`legacy resume provider mismatch: ${$.provider} != ${this.selectedProvider}`);let Z;if($.provider==="claude"){let J=B7(this.workDir,$.sessionId);if(!wW(J))throw Error(`旧 Claude 会话不属于当前 cwd,或 transcript 不存在: ${V0($.sessionId)}`);Z={...$,cwd:this.workDir}}else{if(!k2())throw Error("Codex 未登录 ChatGPT 账号");let J=this.currentTokenSource();if(this.selectedTokenSourceId&&(!J||!J.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或选择其他账号`);let Y=J?.enabled?J:void 0,Q=new M1({workDir:this.workDir,launch:{kind:"fresh"},tokenSourceId:Y?.id??null,transformEnv:Y?(X)=>Y.spawnEnv(X):void 0}),W=null;try{Z=await Q.readConversationRef($.sessionId)}catch(X){W=X,Z=$}let H=null;try{await Q.kill(2000)}catch(X){H=X}if(W&&H)throw AggregateError([W,H],`Codex legacy resume lookup and cleanup failed: read=${F(W)}; cleanup=${F(H)}`);if(W)throw W;if(H)throw H}return z0({kind:"resume",source:Z},this.selectedProvider,this.workDir),M2(this.sessionName,Z),Z}hasRunningPeerSession($){return[...z1.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)return;return S0(this.selectedEffort)?this.selectedEffort:G2}return G2}claudeEffortForSpawn(){return this.selectedProvider==="claude"&&a0(this.selectedEffort)?this.selectedEffort:P$}currentModelLabel(){return(this.selectedModel??this.currentTokenSource()?.defaultModel??this.proc?.lastModel??null)?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null}currentEffortLabel(){return this.selectedEffort??this.proc?.lastEffort??(this.selectedProvider==="claude"?P$:G2)}runtimeModelSelection(){let $=this.proc?.isAlive()?this.proc:null,Z=$?.provider??this.selectedProvider,J=!$||$.provider===this.selectedProvider,Y=($?.lastModel??(J?this.currentModelLabel():null))?.replace(/^claude:/i,"").replace(/\[1m\]$/i,"")??null,Q=$?.lastEffort??(J?this.currentEffortLabel():Z==="claude"?P$:G2);return{provider:Z,model:Y,effort:Q}}modelEffortLabel($=this.currentTurn??this.runtimeModelSelection()){let Z=$.provider==="claude"?$.model?.replace(/^claude:/i,"").replace(/\[1m\]$/i,""):$.model,J=Z?`${Z}/${$.effort}`:$.effort;return $.provider==="claude"?`${J$($.provider)} · ${J}`:J}withModel($,Z){let J=this.modelEffortLabel(Z);return $.includes(J)?$:`${$} · ${J}`}replaceFooterContent($,Z){return n($,M.footer,this.footerElement(Z),void 0,!1)}footerElement($){return{tag:"markdown",element_id:M.footer,content:$.trim()||" "}}modelLine($){return this.modelEffortLabel($)}backendLabel($=this.selectedProvider){return J$($)}pendingConversationLaunch=null;pendingConversationMaterialization=null;lastTurnUserPreview="";pendingCodexTurnAnchors=[];pendingMaterializationLaunch(){let $=this.pendingConversationMaterialization;if(!$)return null;if(z0($.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=aK(32).toString("base64url");let Z={LODESTAR_AGENT_URL:f4(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:this.agentCapability,LODESTAR_AGENT_SESSION:this.sessionName,LODESTAR_AGENT_ROLE:"main"},J=this.pendingConversationLaunch??this.pendingMaterializationLaunch()??($?{kind:"resume",source:$}:{kind:"fresh"});z0(J,this.selectedProvider,this.workDir);let Y=this.currentTokenSource();if(this.selectedTokenSourceId&&(!Y||!Y.enabled))throw Error(`token source "${this.selectedTokenSourceId}" 不可用,请重新配置或在 model 面板选择其他账号`);let Q=Y?.enabled?Y:void 0,W=w4({provider:this.selectedProvider,workDir:this.workDir,tokenSourceId:Q?.id??null,model:Q?this.selectedModel??Q.defaultModel:this.modelForSpawn(),effort:this.selectedProvider==="claude"?this.claudeEffortForSpawn():this.effortForSpawn(),launch:J,developerInstructions:this.spawnDeveloperInstructions(),profile:y1(this.worktreeProjectName()),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:w$},hostEnv:Z});return this.procSourceRevisions.set(W.process,W.sourceRevision),W.process}async applyModelSelection($,Z,J,Y){await this.runLifecycle("apply-model-selection",()=>this.applyModelSelectionUnlocked($,Z,J,Y))}async applyModelSelectionUnlocked($,Z,J,Y){if(this.selectedProvider!==$)m0(this.sessionName,[],null,null),this.pendingConversationMaterialization=null;this.selectedProvider=$,this.selectedTokenSourceId=Y??this.selectedTokenSourceId;let W=$0(this.selectedTokenSourceId);if(W)this.selectedModel=Z||null,this.selectedEffort=J??W.models.find((H)=>H.model===Z)?.defaultEffort??W.models[0]?.defaultEffort??null;else this.selectedModel=$==="codex"?null:Z,this.selectedEffort=$==="codex"?null:J;this.lastSessionRef=d$(this.sessionName,$),this.lastSessionId=this.lastSessionRef?.sessionId??null,I7(this.sessionName,$,this.selectedModel,this.selectedEffort,this.selectedTokenSourceId),await this.stopIdleMismatchedProcessUnlocked()}async stopIdleMismatchedProcess(){await this.runLifecycle("stop-idle-mismatched",()=>this.stopIdleMismatchedProcessUnlocked())}async stopIdleMismatchedProcessUnlocked(){if(!this.proc?.isAlive())return;let $=this.currentTokenSource(),Z=!this.procSourceRevisions.has(this.proc)||this.procSourceRevisions.get(this.proc)===($?.spawnRevision??null);if(this.proc.provider===this.selectedProvider&&this.proc.tokenSourceId===this.selectedTokenSourceId&&Z)return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0)return;let J=this.proc;A(`session "${this.sessionName}": stop idle ${J.provider} process after switching to ${this.selectedProvider}`),this.beginProcStop(J),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let Y=await this.settleProcResumableState(J),Q=null;try{await J.kill(1000)}catch(X){Q=X}Y=await this.settleProcResumableState(J);let W=this.finishProcStop(J,Q);this.opts.onLifecycleChange?.();let H=[...!W?[Q??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...Y?[Error(Y)]:[]];if(H.length===1)throw H[0];if(H.length>1)throw AggregateError(H,`idle process stop failed: ${H.map(F).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;A(`session "${this.sessionName}": stop idle ${Z.provider} process: ${$}`),this.beginProcStop(Z),this.initCount=0,this.bgResumePending=!1,this.discardOrphanAssistant(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1,this.status="stopped";let J=await this.settleProcResumableState(Z),Y=null;try{await Z.kill(1000)}catch(H){Y=H}J=await this.settleProcResumableState(Z);let Q=this.finishProcStop(Z,Y);this.opts.onLifecycleChange?.();let W=[...!Q?[Y??Error(this.blockedProcReason??"process stop unconfirmed")]:[],...J?[Error(J)]:[]];if(W.length===1)throw W[0];if(W.length>1)throw AggregateError(W,`idle process stop failed: ${W.map(F).join("; ")}`);return!0}startFooterTimer($,Z,J=(Y)=>Y){let Y=Date.now(),Q=Z,W=!1,H=()=>{if(W)return;this.replaceFooterContent($,J(hW(Q,Y)))},X=null,V=()=>{if(W)return;let{nextDelayMs:z}=L$(Date.now()-Y,V1());X=setTimeout(()=>{H(),V()},Math.max(1,Math.ceil(z)))};return H(),V(),{setStatus(z){Q=z,H()},stop(){if(W=!0,X)clearTimeout(X)},elapsedSec(){return((Date.now()-Y)/1000).toFixed(1)}}}async openStatusCard($,Z,J="blue"){let Y=Date.now(),Q=F8({sessionName:this.sessionName,title:$,status:hW(Z,Y),template:J}),W=await i(this.chatId,Q);if(!W)return A(`session "${this.sessionName}": status card send failed title=${$}`),await C(this.chatId,`❌ 创建状态卡片失败: ${$}`),null;let H;try{H=await t0(W)}catch(X){return A(`session "${this.sessionName}": status card id_convert failed title=${$}: ${X}`),await C(this.chatId,`❌ 状态卡片初始化失败: ${$}`),null}return p0(H,1),{cardId:H,title:$,timer:this.startFooterTimer(H,Z,(X)=>g2($,X))}}setStatusCard($,Z){$?.timer.setStatus(Z)}async closeStatusCard($,Z){if(!$)return;$.timer.stop();let J=$.timer.elapsedSec(),Y=g2($.title,`${Z} (${J}s)`);await b0($.cardId);let Q=await R0($.cardId,M.footer,this.footerElement(Y));A0($.cardId);let W=await _0($.cardId,z$({durationSec:J,suffix:Z}));if(Q&&W)await C0($.cardId);else{let H=`footer=${Q?"ok":"MISS"}, settings=${W?"ok":"MISS"}`;A(`session "${this.sessionName}": status card terminal transaction incomplete card=${$.cardId.slice(0,12)} ${H}`),await C(this.chatId,`⚠️ 状态卡片终态写入失败 (${H}):${Z}`)}}async runLifecycle($,Z){let J=this.lifecycleTail,Y;this.lifecycleTail=new Promise((W)=>{Y=W}),await J;let Q=++this.lifecycleSequence;A(`session "${this.sessionName}": lifecycle#${Q} ${$} begin`);try{return await Z()}finally{Y(),A(`session "${this.sessionName}": lifecycle#${Q} ${$} end`)}}beginTurnOpen($=this.proc,Z=this.procEpoch,J=!1){if(this.openingTurnOwner)throw Error(`turn card open already owned by token=${this.openingTurnOwner.token}; same-process opens must wait for the current owner`);let Y,Q=new Promise((H)=>{Y=H}),W={token:++this.turnOpenSequence,proc:$,procEpoch:Z,sawResult:!1,terminalForcePush:!1,pendingCompactions:[],backendTurnStarted:J,done:Q,resolveDone:Y};return this.openingTurnOwner=W,this.openingTurn=!0,W}ownsTurnOpen($){return this.openingTurnOwner===$&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseTurnOpen($){if(this.openingTurnOwner!==$)return;this.openingTurnOwner=null,this.openingTurn=!1,$.resolveDone()}invalidateTurnOpen(){let $=this.openingTurnOwner;this.openingTurnOwner=null,this.openingTurn=!1,$?.resolveDone()}async waitForTurnOpenSlot($,Z){while(this.openingTurnOwner)if(await this.openingTurnOwner.done,this.proc!==$||this.procEpoch!==Z||!$.isAlive())return!1;return this.proc===$&&this.procEpoch===Z&&$.isAlive()}beginBackgroundOpen(){if(this.backgroundCard||this.openingBackgroundOwner)return null;let $={token:++this.backgroundOpenSequence,proc:this.proc,procEpoch:this.procEpoch,generation:this.backgroundGeneration};return this.openingBackgroundOwner=$,this.openingBackground=!0,$}ownsBackgroundOpen($){return this.openingBackgroundOwner===$&&this.backgroundGeneration===$.generation&&this.proc===$.proc&&this.procEpoch===$.procEpoch}releaseBackgroundOpen($){if(this.openingBackgroundOwner!==$)return;this.openingBackgroundOwner=null,this.openingBackground=!1}invalidateBackgroundOpen(){this.backgroundGeneration++,this.openingBackgroundOwner=null,this.openingBackground=!1}attachProc($){this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.stoppingProc=null,this.blockedProc=null,this.blockedProcReason=null,this.proc=$;let Z=++this.procEpoch;this.wireProc($,Z)}detachProc($){if(this.proc!==$)return!1;if(this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.proc=null,this.agentCapability=null,this.stoppingProc===$)this.stoppingProc=null;if(this.blockedProc===$)this.blockedProc=null,this.blockedProcReason=null;return this.procEpoch++,!0}beginProcStop($){this.stoppingProc=$,this.agentCapability=null}acceptsAgentCapability($){let Z=this.agentCapability;if(!Z||!$||!this.proc?.isAlive())return!1;let J=Buffer.from(Z),Y=Buffer.from($);return J.length===Y.length&&oK(J,Y)}async cancelAgentRuns($="用户取消"){await this.opts.onCancelAgentRuns?.(this.sessionName,this.chatId,$)}finishProcStop($,Z){if(this.stoppingProc===$)this.stoppingProc=null;if(!$.isAlive())return this.discardPendingCodexTurnAnchors($,"confirmed process stop"),this.detachProc($),!0;return this.blockedProc=$,this.blockedProcReason=Z?F(Z):"kill returned while process still reports alive",A(`session "${this.sessionName}": process stop unconfirmed; lifecycle blocked: ${this.blockedProcReason}`),!1}blockedProcessMessage(){let $=this.blockedProc;if(!$)return null;if(!$.isAlive())return this.detachProc($),null;return`旧 ${this.backendLabel($.provider)} 进程尚未确认退出,会话已阻断: ${this.blockedProcReason??"未知原因"}`}async stopOwnedProc($,Z){if(this.proc!==$)return!$.isAlive();this.beginProcStop($);let J=null;try{await $.kill(Z)}catch(Y){J=Y}return this.finishProcStop($,J)}async settleProcResumableState($){let Z=null,J=$.conversationMaterializationBarrier?.();if(J)try{await J}catch(W){Z=`Codex 会话落盘确认失败: ${F(W)}`}let Y=$.conversationMaterializationFailure?.();if(Y&&$.isConversationResumable?.()!==!0)Z=`Codex 会话落盘确认失败: ${F(Y)}`;let Q=this.persistResumableSessionId(!1,$,!1);return[Z,Q].filter(Boolean).join(";")||null}resetFreshConversationState(){this.turnCounter=0,this.pendingConversationMaterialization=null,m0(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 startUnlocked($={}){let Z=$.announce??!0,J=$.onStatus,Y=this.blockedProcessMessage();if(Y){if(this.status="stopped",J?.(`❌ ${Y}`),Z)await T(this.chatId,`❌ ${Y}。请重试 stop/restart,或等待旧进程退出。`);return!1}if(this.proc&&!this.proc.isAlive())this.detachProc(this.proc);if(this.isRunning()){if(this.proc?.provider===this.selectedProvider)return J?.(this.withModel(`✅ ${this.backendLabel()} 已运行`)),!0;if(await this.stopIdleMismatchedProcessUnlocked(),this.proc?.isAlive())return J?.(`⚠️ 当前 ${this.backendLabel(this.proc.provider)} turn 尚未结束,模型切换将在后续新 turn 生效`),!0}if(this.selectedProvider==="codex")J?.("\uD83D\uDD0E 检查 Codex 登录");else J?.("\uD83D\uDD0E 检查 Claude Code");if(this.selectedProvider==="codex"&&!k2()){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.("❌ Codex 未登录 ChatGPT 账号"),Z)await T(this.chatId,"❌ Codex 未登录 ChatGPT 账号。\n请在服务器上运行 `codex login` 后再试。");return!1}if(!wW(this.workDir)){if(J?.(`\uD83C\uDD95 创建项目目录 ~/${this.sessionName}`),Z)await T(this.chatId,`\uD83C\uDD95 目录 ~/${this.sessionName} 不存在,正在创建…`);try{r7(this.workDir)}catch(G){if(this.status="stopped",this.opts.onLifecycleChange?.(),J?.(`❌ 创建项目失败: ${G}`),Z)await T(this.chatId,`❌ 创建项目失败: ${G}`);return!1}}if(!$.freshConversationStateAlreadyReset&&!this.pendingConversationMaterialization)this.resetFreshConversationState();this.status="starting",J?.(this.withModel(`\uD83D\uDE80 启动 ${this.backendLabel()}`));let Q;try{await C4(),Q=this.spawnAgent()}catch(G){let _=`${this.backendLabel()} 启动失败: ${F(G)}`;if(A(`session "${this.sessionName}": ${_}`),J?.(`❌ ${_}`),Z)await T(this.chatId,`❌ ${_}`);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}this.attachProc(Q);let W=this.backendLabel(),H=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(Q,vW):null;J?.(this.selectedProvider==="claude"?`⏳ 检查 ${W} 启动`:`⏳ 等待 ${W} init`);let X,V=null;try{if(Q.sendInitialize(),this.selectedProvider==="codex")X=Q.initializationPromise?.()}catch(G){X=void 0,V=G}let z=V?{state:"error",error:V}:this.selectedProvider==="claude"?await H:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(X),()=>{A(`session "${this.sessionName}": codex init still pending after ${C5/1000}s`),J?.(this.withModel(`⏳ 仍在等待 ${W} init 确认`))});if(z.state==="error"||z.state==="exit"){let G=z.error?F(z.error):z.state;A(`session "${this.sessionName}": ${this.selectedProvider} init failed: ${G}`);let B=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,q=`❌ ${W} 启动失败: ${G}${B}`;if(J?.(q),Z)await T(this.chatId,q);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(z.state==="timeout"){A(`session "${this.sessionName}": ${this.selectedProvider} init wait timeout (${J6/1000}s)`);let _=await this.stopOwnedProc(Q,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,B=`❌ ${W} 启动超时: ${J6/1000} 秒内初始化事务未完成${_}`;if(J?.(B),Z)await T(this.chatId,B);return this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(this.proc!==Q||!Q.isAlive()){let G=`${W} 启动期间已退出`;if(A(`session "${this.sessionName}": ${G}`),J?.(`❌ ${G}`),Z)await T(this.chatId,`❌ ${G}`);return this.detachProc(Q),this.status="stopped",this.opts.onLifecycleChange?.(),!1}if(Z){let G=this.modelLine();await T(this.chatId,[this.withWorktreeInstructionNotice(`✅ Lodestar session "${this.sessionName}" 已就绪,发消息开始对话。`),G].filter(Boolean).join(`
186
+ `))}return this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.(),J?.(this.withModel(this.withWorktreeInstructionNotice(`✅ ${this.backendLabel()} 已就绪`))),!0}requireCodexInitializationPromise($){if(!$||typeof $.then!=="function")return Promise.reject(Error("Codex process did not expose its initialization transaction"));return Promise.resolve($)}async waitForCodexInitialization($,Z){return await new Promise((J)=>{let Y=!1,Q=(X,V)=>{if(Y)return;Y=!0,clearTimeout(W),clearTimeout(H),J({state:X,error:V})},W=setTimeout(()=>{if(Y)return;try{Z?.()}catch(X){Q("error",X)}},C5),H=setTimeout(()=>{Q("timeout",Error(`codex init timed out after ${J6/1000}s`))},J6);$.then(()=>Q("init"),(X)=>Q("error",X))})}async waitForProcEarlyFailure($,Z){return await new Promise((J)=>{let Y=!1,Q=(z,G)=>{if(Y)return;Y=!0,clearTimeout(W),$.off("init",H),$.off("error",X),$.off("exit",V),J({state:z,error:G})},W=setTimeout(()=>Q("ready"),Z),H=()=>Q("init"),X=(z)=>Q("error",z),V=(z)=>Q("exit",z);$.once("init",H),$.once("error",X),$.once("exit",V)})}releaseAllReactions(){for(let[$,Z]of[...this.pendingReactionIds.entries(),...this.currentBatchReactionIds.entries()])if(Z)j0($,Z);this.pendingReactionIds=new Map,this.currentBatchReactionIds=new Map}clearStaleIdleQueueState($){if(this.initCount<1||this.currentTurn||this.openingTurn||this.pendingUserMessageCount===0)return;A(`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)j0(Z,J);this.pendingReactionIds=new Map}async stop($="已终止",Z={}){await this.runLifecycle("stop",()=>this.stopUnlocked($,Z))}async stopUnlocked($="已终止",Z={}){let J=Z.announce??!0,Y=Z.onStatus;if(await this.cancelAgentRuns($),!this.proc){if(this.status="stopped",this.opts.onLifecycleChange?.(),Y?.("⚪ session 当前未运行"),J)await T(this.chatId,`⚪ session "${this.sessionName}" 当前未运行`);return}let Q=this.proc,W=this.persistResumableSessionId(!1,Q,!1),H=null;if(Y?.(`\uD83D\uDED1 停止 ${this.backendLabel(this.proc.provider)}`),A(`session "${this.sessionName}": stop (${$})`),this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.currentTurn)this.closeTurnCard(`\uD83D\uDED1 ${$}`).catch((R)=>{A(`session "${this.sessionName}": stop current main-card close failed: ${F(R)}`)});let X=this.waitForTurnCloses().catch((R)=>A(`session "${this.sessionName}": stop main-card close failed: ${F(R)}`));this.beginProcStop(Q),this.status="stopped";let V=[];try{this.opts.onLifecycleChange?.()}catch(R){V.push(R),A(`session "${this.sessionName}": stop intent lifecycle write failed: ${F(R)}`)}let z=Q.conversationMaterializationBarrier?.();if(z){try{await z}catch(R){H=`Codex 会话落盘确认失败: ${F(R)}`}W=this.persistResumableSessionId(!1,Q,!1)}this.clearMultiMsgBuffer("stop"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.bgResumePending=!1,this.discardOrphanAssistant(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1,this.usageTotalsSeedUnknown=!1;let G=null;try{await Q.kill()}catch(R){G=R}let _=Q.conversationMaterializationFailure?.();if(_&&Q.isConversationResumable?.()!==!0)H=`Codex 会话落盘确认失败: ${F(_)}`;W=this.persistResumableSessionId(!1,Q,!1);let q=(await Promise.allSettled([this.resetBackgroundTasks(),X])).filter((R)=>R.status==="rejected").map((R)=>R.reason);for(let R of q)A(`session "${this.sessionName}": stop terminal cleanup failed: ${F(R)}`);let L=this.finishProcStop(Q,G);try{this.opts.onLifecycleChange?.()}catch(R){V.push(R),A(`session "${this.sessionName}": stop final lifecycle write failed: ${F(R)}`)}let P=[...G?[G]:[],...!L&&!G?[Error(this.blockedProcReason??"process stop unconfirmed")]:[],...q,...V,...W?[Error(W)]:[],...H&&Q.isConversationResumable?.()!==!0?[Error(H)]:[]];if(P.length===1)throw P[0];if(P.length>1)throw AggregateError(P,`stop failed: ${P.map(F).join("; ")}`);if(Y?.(`✅ ${$}`),J)await T(this.chatId,`\uD83D\uDD34 ${$} (session: ${this.sessionName})`)}async restart($=!1,Z={}){return await this.runLifecycle("restart",()=>this.restartUnlocked($,Z))}async restartUnlocked($=!1,Z={},J){let Y=Z.announce??!0,Q=Z.onStatus,W=this.status,H=null;if(!$&&!this.pendingConversationLaunch&&this.pendingConversationMaterialization)H=this.pendingConversationMaterialization,R$(this.sessionName,null),this.pendingConversationMaterialization=null;let X=this.pendingConversationLaunch??this.pendingMaterializationLaunch(),V=this.lastSessionRef;if($&&!X&&V?.cwd===null)try{V=await this.resolveLegacyResumeRef(V),this.lastSessionRef=V,this.lastSessionId=V.sessionId}catch(S){let k=this.invalidateMissingCodexResume(V.sessionId,S,J),h=k?`❌ 旧会话不可恢复: ${F(S)};${k}`:`❌ 旧会话 cwd 校验失败: ${F(S)};请在进程已停时发送 rs 重新选择历史会话`;if(this.status=this.proc?.isAlive()?W:"stopped",Q?.(h),Y)await T(this.chatId,h);return!1}let z=V?.sessionId??null,G=X&&X.kind!=="fresh"?X.source.sessionId:z,_=G?V0(G):"",B=null,q=(S=this.proc)=>{if(!$||X||S?.provider!=="codex"||S.isConversationResumable?.()!==!0)return;B=this.persistResumableSessionId(!1,S,!1),V=this.lastSessionRef,z=V?.sessionId??null,G=z,_=G?V0(G):""},L=null;if(!Q&&Y&&$&&z){let S=this.proc?this.withModel(`\uD83D\uDD01 重启 ${this.backendLabel(this.proc.provider)}`):this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`);if(L=await this.openStatusCard("restart",S),L)Q=(k)=>this.setStatusCard(L,k)}let P=Y&&!L,R=async(S)=>{if(L)await this.closeStatusCard(L,S)},O=Boolean(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0||this.pendingTurnInputs.length>0||this.backgroundTasks.length>0||this.pendingBgTasks.length>0||this.openingBackground);if(this.bgResumePending=!1,this.invalidateTurnOpen(),this.invalidateBackgroundOpen(),this.discardOrphanAssistant(),this.currentTurn)this.closeTurnCard("\uD83D\uDD01 已中止,正在重启").catch((S)=>{A(`session "${this.sessionName}": restart current main-card close failed: ${F(S)}`)});let j=this.waitForTurnCloses().catch((S)=>A(`session "${this.sessionName}": restart main-card close failed: ${F(S)}`)),D=null,E=null;if(this.proc){let S=this.proc;Q?.(`\uD83D\uDED1 停止当前 ${this.backendLabel(S.provider)}`),E=S,this.beginProcStop(S);let k=S.conversationMaterializationBarrier?.();if(k)try{await k}catch(U){B=`Codex 会话落盘确认失败: ${F(U)}`}if(q(S),$&&!X&&B&&!O&&S.isAlive()){if(this.stoppingProc===S)this.stoppingProc=null;this.status=W;let U=`❌ ${this.backendLabel(S.provider)} 恢复点尚未安全落盘,已保留当前进程: ${B}`;if(A(`session "${this.sessionName}": abort restart before kill: ${B}`),Q?.(U),P)await T(this.chatId,U);return await R(U),!1}try{await S.kill()}catch(U){D=U}let h=S.conversationMaterializationFailure?.();if(h&&S.isConversationResumable?.()!==!0)B=`Codex 会话落盘确认失败: ${F(h)}`;q(S)}this.clearMultiMsgBuffer("restart"),this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),this.initCount=0,this.invalidateTurnOpen(),this.pendingAsks.clear(),this.pendingPermissions.clear(),this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let b=(await Promise.allSettled([this.resetBackgroundTasks(),j])).filter((S)=>S.status==="rejected").map((S)=>S.reason);for(let S of b)A(`session "${this.sessionName}": restart terminal cleanup failed: ${F(S)}`);let u=E?this.finishProcStop(E,D):!0,g=[...D?[`kill=${F(D)}`]:[],...!u&&!D?[`kill=${this.blockedProcReason??"process stop unconfirmed"}`]:[],...b.map((S)=>`cleanup=${F(S)}`),...B?[`resume=${B}`]:[]];if(g.length>0&&H)try{R$(this.sessionName,H),this.pendingConversationMaterialization=H}catch(S){g.push(`pendingRestore=${F(S)}`)}if(g.length>0){let S=`❌ 旧 ${this.backendLabel()} 进程停止/清理失败: ${g.join("; ")}`;if(this.status="stopped",this.opts.onLifecycleChange?.(),Q?.(S),P)await T(this.chatId,S);return await R(S),!1}let c=X?.kind==="resume"||X?.kind==="fork";if($&&V||c){this.status="starting",this.usageTotalsSeedUnknown=!0,Q?.(this.withModel(`\uD83D\uDD01 恢复上一会话 thread=${_}`));let S;try{await C4(),S=this.spawnAgent(V??void 0)}catch(W0){let F0=`❌ ${this.backendLabel()} 恢复失败: ${F(W0)}`;if(A(`session "${this.sessionName}": ${this.selectedProvider} resume failed before spawn: ${F(W0)}`),Q?.(F0),P)await T(this.chatId,F0);return this.status="stopped",this.opts.onLifecycleChange?.(),await R(F0),!1}this.attachProc(S);let k=this.backendLabel(),h=this.selectedProvider==="claude"?this.waitForProcEarlyFailure(S,vW):null;Q?.(this.selectedProvider==="claude"?`⏳ 检查 ${k} 恢复启动`:`⏳ 等待 ${k} init 确认`);let U,y=null;try{if(S.sendInitialize(),this.selectedProvider==="codex")U=S.initializationPromise?.()}catch(W0){U=void 0,y=W0}let w=y?{state:"error",error:y}:this.selectedProvider==="claude"?await h:await this.waitForCodexInitialization(this.requireCodexInitializationPromise(U),()=>{A(`session "${this.sessionName}": codex resume init still pending after ${C5/1000}s`),Q?.(this.withModel(`⏳ 仍在等待 ${k} init 确认 thread=${_}`))});if(w.state==="error"||w.state==="exit"||w.state==="timeout"){let W0=w.state==="error"?this.invalidateMissingCodexResume(G,w.error,J):null,F0=[w.error?F(w.error):w.state,W0].filter(Boolean).join(";");A(`session "${this.sessionName}": ${this.selectedProvider} resume failed: ${F0}`);let Q2=await this.stopOwnedProc(S,1000)?"":`;进程终止未确认: ${this.blockedProcReason??"未知原因"}`,h0=w.state==="timeout"?`❌ ${k} 恢复超时${Q2}`:`❌ ${k} 恢复失败: ${F0}${Q2}`;if(Q?.(h0),P)await T(this.chatId,h0);return this.status="stopped",this.opts.onLifecycleChange?.(),await R(h0),!1}if(this.proc!==S||!S.isAlive()){let W0=`❌ ${k} 恢复期间已退出`;if(A(`session "${this.sessionName}": ${this.selectedProvider} resume process exited before ready`),Q?.(W0),P)await T(this.chatId,W0);return this.detachProc(S),this.status="stopped",this.opts.onLifecycleChange?.(),await R(W0),!1}let M0=this.withModel(this.withWorktreeInstructionNotice(this.selectedProvider==="claude"&&w.state==="ready"?`✅ 已准备恢复上一会话 thread=${_}`:`✅ 已恢复上一会话 thread=${_}`));if(Q?.(M0),P)await T(this.chatId,M0);this.status="idle",this.startedAt=Date.now(),this.opts.onLifecycleChange?.();try{await R(M0)}catch(W0){A(`session "${this.sessionName}": restart succeeded but status-card close failed: ${F(W0)}`),await C(this.chatId,`⚠️ ${M0}
187
+ 状态卡收尾失败: ${F(W0)}`)}return!0}else{if($&&!X){if(Q?.("⚠️ 没有可恢复的上一会话,将以新会话启动"),P)await T(this.chatId,"⚠️ 没有可恢复的上一会话,将以新会话启动")}return this.resetFreshConversationState(),await this.startUnlocked({...Z,freshConversationStateAlreadyReset:!0})}}async startForked($,Z={}){return await this.runLifecycle("start-forked",async()=>{z0($,this.selectedProvider,this.workDir);let J=O2(this.sessionName),Y=this.selectedProvider==="claude"?{launch:$,previousSessionId:this.lastSessionId}:null;if(Y)R$(this.sessionName,Y),this.pendingConversationMaterialization=Y;this.pendingConversationLaunch=$;try{let Q=await this.startUnlocked(Z);if(!Q&&Y)R$(this.sessionName,J),this.pendingConversationMaterialization=J;return Q}catch(Q){if(!Y)throw Q;try{R$(this.sessionName,J),this.pendingConversationMaterialization=J}catch(W){throw AggregateError([Q,W],`fork start and pending-intent restore failed: ${F(Q)}; ${F(W)}`)}throw Q}finally{this.pendingConversationLaunch=null}})}async rollbackTo($,Z,J={}){return await this.runLifecycle("rollback",async()=>{z0($,this.selectedProvider,this.workDir);let Y=Z?{anchors:Z.anchors.slice(),base:Z.base,pendingLaunch:Z.pendingLaunch!==void 0?Z.pendingLaunch:this.selectedProvider==="claude"&&$.kind==="fork"?{launch:$,previousSessionId:this.lastSessionId}:null}:null,Q=this.proc,W=this.lastSessionId,H=this.lastSessionRef,X=F2(this.sessionName).slice(),V=U2(this.sessionName),z=O2(this.sessionName),G={turnCounter:this.turnCounter,currentGoal:this.currentGoal,cumStats:{...this.cumStats},lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,currentTurnUsageBaseline:this.currentTurnUsageBaseline?{...this.currentTurnUsageBaseline}:null,currentTurnUsageBaselineKnown:this.currentTurnUsageBaselineKnown,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,usageTotalsSeedUnknown:this.usageTotalsSeedUnknown},_=!1,B=()=>{if(_)this.lastSessionId=null,this.lastSessionRef=null,x1(this.sessionName,"codex");else if(this.lastSessionId=W,this.lastSessionRef=H,H)M2(this.sessionName,H);else x1(this.sessionName,this.selectedProvider);m0(this.sessionName,X,V,z),this.pendingConversationMaterialization=z,this.turnCounter=G.turnCounter,this.currentGoal=G.currentGoal,this.cumStats=G.cumStats,this.lastTurnDelta=G.lastTurnDelta,this.currentTurnUsageBaseline=G.currentTurnUsageBaseline,this.currentTurnUsageBaselineKnown=G.currentTurnUsageBaselineKnown,this.lastTurnUsage=G.lastTurnUsage,this.usageTotalsSeedUnknown=G.usageTotalsSeedUnknown},q=!1;if(Y?.pendingLaunch)m0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch),this.pendingConversationMaterialization=Y.pendingLaunch,q=!0;this.pendingConversationLaunch=$;let L=(P)=>{_=H?.provider==="codex"&&H.sessionId===P};try{let P;try{P=$.kind==="fresh"?await this.restartUnlocked(!1,J,L):await this.restartUnlocked(!0,J,L)}catch(R){let O=null,j=this.proc&&this.proc!==Q?this.proc:null;if(j)try{await this.stopUnlocked("回滚启动事务失败",{announce:!1})}catch(b){O=b}let D=!j||this.proc!==j&&!j.isAlive();if(!D&&!O)O=Error("replacement process stop was not confirmed");let E=null;if(D)try{B()}catch(b){E=b}let x=[R,...O?[O]:[],...E?[E]:[]];if(x.length===1)throw R;throw AggregateError(x,`rollback launch and cleanup failed: ${x.map(F).join("; ")}`)}if(!P)return B(),!1;if(Y)try{if(!q)m0(this.sessionName,Y.anchors,Y.base,Y.pendingLaunch);this.pendingConversationMaterialization=Y.pendingLaunch}catch(R){let O=null,j=this.proc;try{await this.stopUnlocked("回滚分支状态持久化失败",{announce:!1})}catch(b){O=b}let D=!j||this.proc!==j&&!j.isAlive();if(!D&&!O)O=Error("replacement process stop was not confirmed");let E=null;if(D)try{B()}catch(b){E=b}let x=[R,...O?[O]:[],...E?[E]:[]];if(x.length===1)throw R;throw AggregateError(x,`rollback branch commit failed: ${x.map(F).join("; ")}`)}return P}finally{this.pendingConversationLaunch=null}})}dispose(){z1.all.delete(this)}recordTurnAnchor($){let Z=this.proc;if(!Z?.sessionId||!$)return null;if($.provider!==Z.provider||$.source.sessionId!==Z.sessionId||$.source.cwd!==this.workDir){let Y=`拒绝了与当前会话不匹配的 checkpoint provider=${$.provider} source=${$.source.sessionId}`;return A(`session "${this.sessionName}": ${Y}`),this.lastTurnUserPreview="",Y}let J={checkpoint:$,preview:this.lastTurnUserPreview.slice(0,80),ts:Date.now(),writes:this.collectTurnWrites()};if(this.lastTurnUserPreview="",Z.provider==="codex"&&Z.isConversationResumable?.()!==!0){if(this.pendingCodexTurnAnchors.filter((Q)=>Q.proc===Z).length>=64)return A(`session "${this.sessionName}": ${"Codex rollout 长期未确认,延迟 checkpoint 队列已满"} thread=${Z.sessionId}`),"Codex rollout 长期未确认,延迟 checkpoint 队列已满";return this.pendingCodexTurnAnchors.push({proc:Z,anchor:J}),A(`session "${this.sessionName}": defer Codex turn checkpoint until rollout confirmation thread=${Z.sessionId} checkpoint=${$.id}`),null}return this.appendTurnAnchor(J)}appendTurnAnchor($){try{return v7(this.sessionName,$),null}catch(Z){let J=`分叉 checkpoint 持久化失败: ${F(Z)}`;return A(`session "${this.sessionName}": ${J}`),J}}flushPendingCodexTurnAnchors($){let Z=null,J=[];for(let Y of this.pendingCodexTurnAnchors){if(Y.proc!==$||Z){J.push(Y);continue}if(Z=this.appendTurnAnchor(Y.anchor),Z)J.push(Y)}return this.pendingCodexTurnAnchors=J,Z}discardPendingCodexTurnAnchors($,Z){if($.provider!=="codex")return;let J=this.pendingCodexTurnAnchors.length;this.pendingCodexTurnAnchors=this.pendingCodexTurnAnchors.filter((Q)=>Q.proc!==$);let Y=J-this.pendingCodexTurnAnchors.length;if(Y>0)A(`session "${this.sessionName}": dropped ${Y} unmaterialized Codex checkpoint(s): ${Z}`)}collectTurnWrites(){let $=this.currentTurn;if(!$)return[];let Z=[];for(let J of $.toolByUseId.values())Z.push(...v8(J.name,J.input));return Z}worktreeProjectName(){return y$(this)}worktreeProjectDir(){return r1(this)}spawnDeveloperInstructions(){return KW(this)}delegatedAgentDeveloperInstructions($){return BW(this,$)}worktreeInstructionLoadedNotice(){return k5(this)}withWorktreeInstructionNotice($){return qW(this,$)}worktreeExtraInstruction(){return t2(this)}runWorktreeCommand($,Z){return LW(this,$,Z)}showWorktrees(){return S5(this)}showTasklistPanel(){return lQ(this)}showAgentIdentityPanel($=""){return fQ(this,$)}onAgentIdentityPage($,Z,J){return vQ($,Z,J)}onTasklistEnable(){return iQ(this)}onTasklistDeletePrompt($){return dQ(this,$)}onTasklistDeleteConfirm($){return nQ(this,$)}runCompactCommand(){return UQ(this)}showModelPanel(){return TQ(this)}onModelSelect($,Z="",J="",Y=null){return xQ(this,$,Z,J,Y)}onModelEffortSelect($,Z,J="",Y="",Q=""){return this.runLifecycle("model-effort-select",()=>bQ(this,$,Z,J,Y,Q))}onProviderSelect($,Z=""){return NQ(this,$,Z)}onModelPanelCancel($=""){return yQ(this,$)}onModelCustomPrompt($,Z,J=""){return kQ(this,$,Z,J)}consumeModelCustomMessage($,Z){return SQ(this,$,Z)}onWorktreeDisband($){return jW(this,$)}showForkList($=""){return EW(this,$)}showBackList($=""){return TW(this,$)}showResumeList($=""){return NW(this,$)}runBtwCommand($){return kW(this,$)}runByeCommand(){return SW(this)}onForkSelect($,Z,J=""){return yW(this,$,Z,J)}onBackSelect($,Z,J=""){return xW(this,$,Z,J)}onResumeSelect($,Z,J=""){return bW(this,$,Z,J)}runCommand($,Z=""){return MQ(this,$,Z)}async buildConsoleOpts($,Z){let J=await lJ(),Y=this.runtimeModelSelection();return{sessionName:this.sessionName,status:this.status,provider:Y.provider,model:Y.model??void 0,effort:Y.effort,worktreeInstructionNotice:this.worktreeInstructionLoadedNotice(),peers:[...z1.all].filter((Q)=>Q.isRunning()).map((Q)=>({...Q.peerSnapshot(),isCurrent:Q===this})),usage:$,glmUsage:Z,sysinfo:J}}async buildConsoleCard($){return U8(await this.buildConsoleOpts($))}async patchConsoleUsage($){let Z=await this.buildConsoleOpts(void 0),J=Z.provider??this.currentProvider(),Y=this.currentTokenSource(),Q=Y&&Y.agent===J&&Y.enabled?Y:this.selectedTokenSourceId?void 0:b4(J)[0];if(Q)Z.unifiedUsage=await Q.readUsage();else if(this.selectedTokenSourceId)Z.unifiedUsage={state:"no_credentials",windows:[],reason:`token source ${this.selectedTokenSourceId} unavailable`};else if(Z.provider==="claude")Z.glmUsage=await r8();else Z.usage=await y9();if(!await R0($,M.consoleUsage,I2(Z),{notifyCardFailure:!1}))throw Error("console usage element replace rejected")}async mutateStaticCard($,Z,J){let Y=!0;try{await J()}catch(W){Y=!1,A(`session "${this.sessionName}": ${Z} mutation failed: ${F(W)}`)}let Q=!1;try{Q=await _0($,{config:{streaming_mode:!1}})}catch(W){A(`session "${this.sessionName}": ${Z} streaming-off failed: ${F(W)}`)}if(!Y||!Q)return A(`session "${this.sessionName}": ${Z} state retained after checked MISS mutation=${Y} streamingOff=${Q} card=${$.slice(0,12)}`),!1;try{await C0($)}catch(W){return A(`session "${this.sessionName}": ${Z} dispose failed: ${F(W)}`),!1}return Y}patchConsoleUsageLater($){this.mutateStaticCard($,"console usage",()=>this.patchConsoleUsage($))}async replaceStatusCardWithConsole($,Z){$.timer.stop();let J=$.timer.elapsedSec(),Y=await this.buildConsoleOpts(void 0);await b0($.cardId);let Q=await R0($.cardId,M.footer,q9(Y,M.footer)),W=await M$($.cardId,B9(Y),{type:"insert_after",targetElementId:M.footer}),H=await M$($.cardId,L9(Y.sysinfo),{type:"insert_after",targetElementId:M.consoleProjects}),X=await M$($.cardId,I2(Y),{type:"insert_after",targetElementId:M.consoleHost});if(!Q||!W||!H||!X){await C(this.chatId,"⚠️ 控制台卡片结构写入失败,请重新发送 hi。"),await this.mutateStaticCard($.cardId,"console structure",async()=>{});return}A0($.cardId),await _0($.cardId,z$({durationSec:J,suffix:Z})),this.patchConsoleUsageLater($.cardId)}async showConsole(){let $=await this.buildConsoleCard(void 0),Z=await i(this.chatId,$);if(!Z)return;(async()=>{let J="";try{J=await t0(Z),p0(J,4)}catch(Y){A(`session "${this.sessionName}": console card conversion failed: ${F(Y)}`);return}await this.mutateStaticCard(J,"console usage",()=>this.patchConsoleUsage(J))})().catch((J)=>A(`session "${this.sessionName}": console async update rejected: ${F(J)}`))}interrupt(){if(!this.proc)return;A(`session "${this.sessionName}": interrupt`),this.proc.sendInterrupt()}sendClaimedUserText($,Z){this.pendingUserMessageCount++;try{$.sendUserText(Z,[])}catch(J){throw this.pendingUserMessageCount=Math.max(0,this.pendingUserMessageCount-1),J}}async startColdUserTurn($,Z,J){if(!this.pendingConversationMaterialization)this.resetFreshConversationState();this.pendingTurnInputs.push($);let Y=this.beginTurnOpen();try{let W=await this.openTurnCard(Y,J,"user_message",{initialFooter:"Waiting...(0s)",startThinking:!1,directStart:!0});if(!W||this.currentTurn!==W)return;let H=this.startFooterTimer(W.cardId,`\uD83D\uDE80 启动 ${this.backendLabel()}`,(G)=>this.withModel(G)),X=`\uD83D\uDE80 启动 ${this.backendLabel()}`,V=await this.startUnlocked({announce:!1,freshConversationStateAlreadyReset:!0,onStatus:(G)=>{X=G,H.setStatus(G)}});if(H.stop(),await b0(W.cardId),!V){this.pendingUserMessageCount=0,this.pendingMidTurnMsgs=[],this.pendingTurnInputs=[],this.lastUserOpenId="",this.releaseAllReactions(),await this.closeTurnCard(X.startsWith("❌")?X:"❌ 启动失败",{forcePush:!0});return}let z=this.proc;if(!z?.isAlive()){await this.closeTurnCard(`❌ ${this.backendLabel()} 启动后已退出`,{forcePush:!0});return}this.startThinkingFooter(W),this.sendClaimedUserText(z,Z),this.status="working"}finally{this.releaseTurnOpen(Y)}}async onUserMessage($,Z=[],J="",Y=""){await this.runLifecycle("user-message",()=>this.onUserMessageUnlocked($,Z,J,Y))}async onUserMessageUnlocked($,Z,J,Y){let Q=this.blockedProcessMessage();if(Q){await T(this.chatId,`❌ ${Q}。请重试 stop/restart,或等待旧进程退出。`);return}if(this.clearStaleIdleQueueState("user_message"),this.proc?.isAlive()&&!this.currentTurn&&!this.openingTurn&&this.pendingUserMessageCount===0&&this.pendingMidTurnMsgs.length===0)await this.stopIdleMismatchedProcessUnlocked();let W=this.currentTurn!==null||this.openingTurn||this.pendingUserMessageCount>0||this.pendingMidTurnMsgs.length>0;this.lastUserOpenId=J;let X=(Z.length?Z.map((z)=>`[file: ${z}]`).join(" ")+`
188
+ `:"")+$,V=(z)=>{this.pendingReactionIds.set(z,""),(async()=>{let G=await T0(z,"OneSecond");if(!G)return;if(this.pendingReactionIds.has(z))this.pendingReactionIds.set(z,G);else if(this.currentBatchReactionIds.has(z))this.currentBatchReactionIds.set(z,G);else j0(z,G)})().catch((G)=>{A(`session "${this.sessionName}": reaction tracking failed: ${F(G)}`)})};if(!this.isRunning()){if(this.openingTurn||this.currentTurn){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}await this.startColdUserTurn($,X,J);return}if(this.currentTurn!==null){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}if(!this.openingTurn&&this.initCount>=1){let z=this.proc,G=this.procEpoch,_=this.beginTurnOpen(z,G);try{this.pendingTurnInputs.push($);let B=await this.openTurnCard(_,J,"user_message");if(!B||this.currentTurn!==B)return;if(this.proc!==z||this.procEpoch!==G||!z.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel(z.provider)} 已退出`);return}this.sendClaimedUserText(z,X),this.status="working"}finally{this.releaseTurnOpen(_)}return}if(this.openingTurn||this.pendingUserMessageCount>0){if(this.pendingMidTurnMsgs.push({text:$,wireText:X,userOpenId:J,msgId:Y}),Y)V(Y);return}if(this.pendingTurnInputs.push($),this.sendClaimedUserText(this.proc,X),W&&Y)V(Y)}hasPendingAsk(){return rY(this)}refreshPendingAsks(){g9(this)}askBlockReason($){return i1(this,$)}onMultiMessageInbound($,Z,J,Y){return kY(this,$,Z,J,Y)}clearMultiMsgBuffer($){e8(this,$)}onAskMessageAnswer($,Z,J){return tY(this,$,Z,J)}onAskAnswer($,Z,J,Y){return sY(this,$,Z,J,Y)}onAskCustomAnswer($,Z,J,Y){return G5(this,$,Z,J,Y)}onPermissionDecision($,Z,J){return QQ(this,$,Z,J)}clearResumeBindingForFreshCodex($){if($.isConversationResumable?.())throw Error("fresh Codex thread was unexpectedly marked resumable during init");let Z=d$(this.sessionName,"codex");if(x1(this.sessionName,"codex"),this.selectedProvider==="codex")this.lastSessionRef=null,this.lastSessionId=null;if(Z)A(`session "${this.sessionName}": cleared pre-fresh Codex resume binding thread=${Z.sessionId}`)}invalidateMissingCodexResume($,Z,J){if(!$||this.selectedProvider!=="codex")return null;let Y=w5(Z);if(!Y||!["thread/read","thread/resume","thread/fork"].includes(Y.method)||Y.serverCode!==-32600||Y.serverMessage!==`no rollout found for thread id ${$}`)return null;let Q=d$(this.sessionName,"codex");if(!Q||Q.sessionId!==$)return null;try{x1(this.sessionName,"codex")}catch(H){let X=`已确认恢复点无 rollout,但作废失败: ${F(H)}`;return A(`session "${this.sessionName}": ${X} thread=${$}`),X}if(this.lastSessionRef?.provider==="codex"&&this.lastSessionRef.sessionId===$)this.lastSessionRef=null,this.lastSessionId=null;J?.($);let W=`已作废无 rollout 的恢复点 thread=${V0($)}`;return A(`session "${this.sessionName}": ${W} fullThread=${$}`),W}persistResumableSessionId($=!1,Z=this.proc,J=!0){let Y=Z?.provider==="claude"?this.pendingConversationMaterialization:null,Q=Z?.sessionId;if(!Z)return null;if(Z.provider==="codex"&&Z.isConversationResumable?.()!==!0)return null;if(!Q){if(!Y)return null;let X=Error("Claude pending fork did not provide a materialized session id");if(A(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}let W={provider:Z.provider,sessionId:Q,cwd:this.workDir};if(Y&&(Q===Y.launch.source.sessionId||Y.previousSessionId!==null&&Q===Y.previousSessionId)){let X=Error(`Claude fork did not materialize an independent session id (${Q})`);if(A(`session "${this.sessionName}": ${X.message}`),$)throw X;return X.message}try{M2(this.sessionName,W)}catch(X){let V=`会话恢复点持久化失败: ${F(X)}`,z=this.resumePersistenceError!==V;if(this.resumePersistenceError=V,Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;if(A(`session "${this.sessionName}": ${V}`),$)throw X;if(z&&J)C(this.chatId,`⚠️ ${V};当前进程可继续,但 daemon 重启前请先解决本机状态目录写入问题。`);return V}if(Z.provider===this.selectedProvider)this.lastSessionRef=W,this.lastSessionId=Q;let H=Z.provider==="codex"?this.flushPendingCodexTurnAnchors(Z):null;if(H){let X=this.resumePersistenceError!==H;if(this.resumePersistenceError=H,$)throw Error(H);if(X&&J)C(this.chatId,`⚠️ ${H}`);return H}return this.resumePersistenceError=null,null}consumePendingConversationMaterialization(){let $=this.pendingConversationMaterialization;if(!$)return null;let Z=this.lastSessionRef;if(Z?.provider!=="claude"||Z.cwd!==this.workDir||Z.sessionId===$.launch.source.sessionId||Z.sessionId===$.previousSessionId)return A(`session "${this.sessionName}": ${"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker"}`),"Claude 待生成分支没有可验证的新会话恢复点,保留 pending marker";try{return R$(this.sessionName,null),this.pendingConversationMaterialization=null,null}catch(J){let Y=`Claude 待生成分支标记清除失败: ${F(J)}`;return A(`session "${this.sessionName}": ${Y}`),Y}}bgStore(){return{active:this.backgroundTasks,pending:this.pendingBgTasks}}applyBgStore($){this.backgroundTasks=$.active,this.pendingBgTasks=$.pending}onMainThreadAdvance(){if(this.pendingBgTasks.length===0)return;this.applyBgStore(e6(this.bgStore())),this.onBackgroundTaskChanged()}bgTaskOwns($){return this.backgroundTasks.some((Z)=>Z.toolUseId===$)||this.pendingBgTasks.some((Z)=>Z.toolUseId===$)}onBackgroundTaskChanged(){if(this.migratingBackgroundCard){this.pendingRebuildBackgroundCard=!0;return}if(!g$(this.backgroundTasks)){if(this.backgroundCard)this.settleBackgroundCard().catch((Z)=>{A(`session "${this.sessionName}": background settle failed: ${F(Z)}`)});return}if(!this.backgroundCard&&!this.openingBackground){this.openBackgroundCard().catch((Z)=>{A(`session "${this.sessionName}": background open failed: ${F(Z)}`)});return}this.scheduleBackgroundRefresh()}async openBackgroundCard(){let $=this.beginBackgroundOpen();if(!$)return;let Z=this.backgroundTasks.slice();try{let J=Q7(Z,Date.now(),V1()),Y=await i(this.chatId,J);if(!Y){if(this.ownsBackgroundOpen($))A(`session "${this.sessionName}": background card send failed`);return}let Q;try{Q=await t0(Y)}catch(W){A(`session "${this.sessionName}": background card id_convert failed: ${W}`);return}if(p0(Q,Z.length),!this.ownsBackgroundOpen($)){await this.terminalizeSupersededCard(Q,"⚠️ 后台任务世代已切换,本卡已作废",!1);return}if(this.backgroundCard={messageId:Y,cardId:Q},this.backgroundDetailAdded=new Set(Z.map((W)=>W.id)),this.backgroundDetailAdding.clear(),A(`session "${this.sessionName}": background card opened cardId=${Q.slice(0,12)} tasks=${Z.length}`),!g$(this.backgroundTasks)){this.settleBackgroundCard().catch((W)=>{A(`session "${this.sessionName}": background settle-after-open failed: ${F(W)}`)});return}this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}finally{this.releaseBackgroundOpen($)}}startBackgroundRefreshTick(){if(this.backgroundRefreshTick)return;let $=()=>{if(this.migratingBackgroundCard||!this.backgroundCard||!g$(this.backgroundTasks))return;let Z=V1(),J=Date.now(),Y=1/0;for(let Q of this.backgroundTasks){if(x0(Q))continue;let W=L$(J-Q.startedAt,Z).nextDelayMs;if(W<Y)Y=W}if(!isFinite(Y))return;this.backgroundRefreshTick=setTimeout(()=>{this.refreshBackgroundCardFull(),$()},Math.max(1,Math.ceil(Y)))};$()}stopBackgroundRefreshTick(){if(this.backgroundRefreshTick)clearTimeout(this.backgroundRefreshTick),this.backgroundRefreshTick=null}scheduleBackgroundRefresh(){if(!this.backgroundCard||this.settlingBackgroundCard||this.migratingBackgroundCard)return;if(this.backgroundRefreshTimer)return;this.backgroundRefreshTimer=setTimeout(()=>{this.backgroundRefreshTimer=null,this.refreshBackgroundCardFull()},1500)}refreshBackgroundCardFull(){if(this.migratingBackgroundCard)return;let $=this.backgroundCard;if(!$)return;let Z=Date.now(),J=V1();for(let Y of this.backgroundTasks)if(!this.backgroundDetailAdded.has(Y.id)){if(this.backgroundDetailAdding.has(Y.id))continue;this.backgroundDetailAdding.add(Y.id),M$($.cardId,U1(Y,Z,J)).then((Q)=>{if(Q)this.backgroundDetailAdded.add(Y.id);else A(`session "${this.sessionName}": background panel add MISS task=${Y.id}`)}).finally(()=>{this.backgroundDetailAdding.delete(Y.id)})}else n($.cardId,A2.panel(Y.id),U1(Y,Z,J));H$($.cardId,U4(this.backgroundTasks))}async resetBackgroundTasks(){if(this.invalidateBackgroundOpen(),this.backgroundTasks.some(($)=>!x0($))){let $=Date.now();this.backgroundTasks=this.backgroundTasks.map((Z)=>x0(Z)?Z:{...Z,status:"killed",endTime:Z.endTime??$})}if(this.pendingBgTasks=[],this.backgroundCard)await this.settleBackgroundCard();if(this.stopBackgroundRefreshTick(),this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.backgroundTasks=[],this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear()}async settleBackgroundCard(){if(this.migratingBackgroundCard)try{await this.migratingBackgroundCard}catch(J){A(`session "${this.sessionName}": background migration failed before settle; retry terminal snapshot: ${F(J)}`)}let $=this.backgroundCard;if(!$||this.settlingBackgroundCard)return;this.settlingBackgroundCard=!0;let Z=[...this.backgroundTasks];if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;this.stopBackgroundRefreshTick();try{if(await b0($.cardId),await r0($.messageId,O4(Z)),A0($.cardId),!await _0($.cardId,z$({suffix:"\uD83E\uDDED 后台任务已结束"})))throw Error("background history streaming-off rejected");if(await C0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((Y)=>!x0(Y)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),A(`session "${this.sessionName}": background card settled cardId=${$.cardId.slice(0,12)} remaining=${this.backgroundTasks.length}`)}finally{if(this.settlingBackgroundCard=!1,this.backgroundCard===$&&g$(this.backgroundTasks))this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(this.backgroundTasks.length>0)this.onBackgroundTaskChanged()}migrateBackgroundCard(){if(this.migratingBackgroundCard)return this.migratingBackgroundCard;let $=this.backgroundCard;if(!$)return Promise.resolve();let Z=this.performBackgroundCardMigration($),J;return J=Z.finally(()=>{if(this.migratingBackgroundCard===J)this.migratingBackgroundCard=null}),this.migratingBackgroundCard=J,J}async performBackgroundCardMigration($){if(this.backgroundCard!==$)return;if(this.backgroundRefreshTimer)clearTimeout(this.backgroundRefreshTimer),this.backgroundRefreshTimer=null;if(this.stopBackgroundRefreshTick(),await b0($.cardId),this.backgroundCard!==$)return;let Z=[...this.backgroundTasks],J=new Set(Z.filter(x0).map((W)=>W.id)),Y=J.size;if(Y>0)await r0($.messageId,O4(Z));else await r0($.messageId,W7());if(A0($.cardId),!await _0($.cardId,z$({suffix:"\uD83E\uDDED 已迁移至新卡"})))throw Error("background migration streaming-off rejected");if(await C0($.cardId),this.backgroundCard===$)this.backgroundCard=null;this.backgroundTasks=this.backgroundTasks.filter((W)=>!J.has(W.id)||!x0(W)),this.backgroundDetailAdded.clear(),this.backgroundDetailAdding.clear(),A(`session "${this.sessionName}": background card migrated cardId=${$.cardId.slice(0,12)} terminal=${Y} active=${this.backgroundTasks.length}`)}startScheduledTurnCard($,Z,J,Y){if(this.proc!==$||this.procEpoch!==Z||!$.isAlive())return;if(this.currentTurn||this.openingTurn||this.pendingUserMessageCount>0||this.bgResumePending)return;let Q;try{Q=this.beginTurnOpen($,Z,!0)}catch(H){A(`session "${this.sessionName}": scheduled turn-open ownership conflict: ${F(H)}`);return}let W=J.replace(/\s+/g," ").trim();this.lastTurnUserPreview=`⏰ ${W.slice(0,78)}`,A(`session "${this.sessionName}": scheduled wakeup prompt=${Y??"MISS"}`),(async()=>{try{let H=await this.openTurnCard(Q,"","scheduled_wakeup");if(this.proc!==$||this.procEpoch!==Z){if(A(`session "${this.sessionName}": scheduled ${$.provider} turn became stale while opening epoch=${Z}`),H&&this.currentTurn===H)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);return}if(!H||this.currentTurn!==H){if(!this.ownsTurnOpen(Q))return;if(this.bgResumeCardless=!0,Q.sawResult)Q.sawResult=!1,A(`session "${this.sessionName}": scheduled open failed after result — flushing orphan now`),this.flushOrphanAssistantToChat("scheduled open failed, result already arrived");else A(`session "${this.sessionName}": scheduled open failed — orphan text flush will cover the output`)}else if(Q.sawResult)Q.sawResult=!1,A(`session "${this.sessionName}": scheduled result raced card-open — closing freshly-opened card`),await this.closeTurnCard(Q.terminalSuffix,{forcePush:Q.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(Q)}})().catch((H)=>{A(`session "${this.sessionName}": scheduled turn-open handler failed: ${F(H)}`)})}wireProc($,Z){if(Z===void 0)this.invalidateTurnOpen(),this.invalidateBackgroundOpen();let J=Z??++this.procEpoch;if(Z===void 0&&this.proc!==$)this.proc=$;let Y=()=>this.proc===$&&this.procEpoch===J,Q=!1,W=!1,H=(X,V)=>{$.on(X,(z)=>{if(!Y()){if(!Q)Q=!0,A(`session "${this.sessionName}": ignore stale ${$.provider} event=${String(X)} epoch=${J} currentEpoch=${this.procEpoch}`);return}if(X!=="exit"&&(this.stoppingProc===$||this.blockedProc===$)){if(!W)W=!0,A(`session "${this.sessionName}": ignore ${$.provider} event=${String(X)} while process stop is pending`);return}V(z)})};H("error",(X)=>{A(`session "${this.sessionName}": ${$.provider} process error: ${X}`)}),H("init",()=>{if($.provider==="codex"&&$.launchKind==="fresh")this.clearResumeBindingForFreshCodex($);else this.persistResumableSessionId(!0);if(this.initCount++,A(`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)A(`session "${this.sessionName}": SDK init claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;return}let X=this.pendingUserMessageCount>0,V=!X&&this.bgResumePending;if(!X&&!V)return;let z=this.lastUserOpenId,G;try{G=this.beginTurnOpen($,J,!0)}catch(q){A(`session "${this.sessionName}": init turn-open ownership conflict: ${F(q)}`);return}if(this.bgResumePending=!1,X)this.pendingUserMessageCount=0,this.currentBatchReactionIds=this.pendingReactionIds,this.pendingReactionIds=new Map;let _=X?[...this.currentBatchReactionIds.keys()]:[],B=()=>{for(let q of _){let L=this.currentBatchReactionIds.get(q);if(this.currentBatchReactionIds.delete(q),L)j0(q,L)}};(async()=>{try{let q=await this.openTurnCard(G,z,X?"user_message":"bg_task_resume");if(!Y()){if(A(`session "${this.sessionName}": ${$.provider} became stale while opening turn card epoch=${J}`),q&&this.currentTurn===q)await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);B();return}if(!q||this.currentTurn!==q){if(!this.ownsTurnOpen(G)){B();return}if(G.sawResult&&G.terminalSuffix)C(this.chatId,G.terminalSuffix);if(X)A(`session "${this.sessionName}": init-path openTurnCard failed — sendInterrupt + release reactions`),this.proc?.sendInterrupt(),B();else if(this.bgResumeCardless=!0,G.sawResult)G.sawResult=!1,A(`session "${this.sessionName}": bg-resume openTurnCard failed, result already arrived — flushing orphan now`),this.flushOrphanAssistantToChat("bg-resume open failed, result already arrived");else A(`session "${this.sessionName}": bg-resume openTurnCard failed — orphan text flush will cover the output`)}else if(G.sawResult)G.sawResult=!1,A(`session "${this.sessionName}": result raced card-open — closing freshly-opened turn card now`),await this.closeTurnCard(G.terminalSuffix,{forcePush:G.terminalForcePush,hasFreshResult:!0}),this.status="idle";else this.status="working"}finally{this.releaseTurnOpen(G)}})().catch((q)=>{A(`session "${this.sessionName}": init turn-open handler failed: ${F(q)}`)})}),H("scheduled_turn_input",({text:X,promptId:V})=>{if($.provider!=="claude")return;this.startScheduledTurnCard($,J,X,V)}),H("conversation_materialized",({session_id:X,source:V})=>{if($.provider!=="codex")return;if($.sessionId!==X){A(`session "${this.sessionName}": ignore mismatched Codex materialization session=${X} current=${$.sessionId??"MISS"} source=${V}`);return}A(`session "${this.sessionName}": Codex resume point materialized thread=${X} source=${V}`),this.persistResumableSessionId()}),H("conversation_materialization_failed",({session_id:X,source:V,error:z})=>{if($.provider!=="codex"||$.sessionId!==X)return;let G=`Codex 会话落盘确认失败,未写恢复点: ${F(z)}`,_=this.resumePersistenceError!==G;if(this.resumePersistenceError=G,A(`session "${this.sessionName}": ${G} thread=${X} source=${V}`),_)C(this.chatId,`⚠️ ${G}`)}),H("turn_retry",()=>{if(this.currentTurn)this.startThinkingFooter(this.currentTurn)}),H("turn_started",({retry:X})=>{if((this.currentTurn||this.openingTurn)&&this.pendingUserMessageCount>0)A(`session "${this.sessionName}": turn_started claimed eager input pendingCount=${this.pendingUserMessageCount}`),this.pendingUserMessageCount=0;if(this.persistResumableSessionId(),X){if(this.currentTurn)this.startThinkingFooter(this.currentTurn);return}let V=this.proc?.lastTotalUsage;if(this.usageTotalsSeedUnknown&&!V){this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;return}this.currentTurnUsageBaseline=V?{...V}:null,this.currentTurnUsageBaselineKnown=!0}),H("token_usage",({totalUsage:X})=>{if(this.persistResumableSessionId(),X)this.usageTotalsSeedUnknown=!1}),H("turn_plan_updated",(X)=>{this.handleTurnPlanUpdated(X)}),H("plan_delta",(X)=>{this.handlePlanDelta(X)}),H("context_compacted",(X)=>{this.handleContextCompacted(X)}),H("rate_limits_updated",(X)=>{if($.provider==="codex")qY(X)}),H("thread_goal_updated",(X)=>{this.handleThreadGoalUpdated(X)}),H("thread_goal_cleared",()=>{this.handleThreadGoalCleared()}),H("assistant_text",({text:X,parentToolUseId:V})=>{if(V)return;this.appendAssistant(X)}),H("assistant_block_stop",({parentToolUseId:X})=>{if(X)return;this.finalizeCurrentAssistantSegment(),this.onMainThreadAdvance()}),H("tool_use",({id:X,name:V,input:z,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(Z7({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,V,z)),this.onBackgroundTaskChanged();return}if(ZQ(this,X,V,z),!G)this.onMainThreadAdvance();if(!G&&(V==="Task"||V==="Agent"))this.lastMainTaskToolUseId=X}),H("tool_result",({tool_use_id:X,content:V,is_error:z,parentToolUseId:G})=>{if(G&&this.bgTaskOwns(G)){this.applyBgStore(Y7({active:this.backgroundTasks,pending:this.pendingBgTasks},G,X,V,z)),this.onBackgroundTaskChanged();return}JQ(this,X,V,z)}),H("can_use_tool",(X)=>{WQ(this,X)}),H("hook_callback",(X)=>{this.proc?.sendHookResponse(X.request_id,{})}),H("result",(X)=>{let V=this.persistResumableSessionId(),z=V?null:this.consumePendingConversationMaterialization(),G=[V,z].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 E=this.proc?.lastResult.subtype??"unknown",x=this.proc?.lastResult.is_error===!0;A(`session "${this.sessionName}": SDK result after user stop subtype=${E} isError=${x} — ignored`),this.status="idle";return}let _=X?.is_error!==!0?this.recordTurnAnchor(X?.checkpoint):null;if(X?.is_error===!0)this.lastTurnUserPreview="";if(!this.currentTurn&&!this.openingTurn)this.flushOrphanAssistantToChat("result with no turn card");let B=this.pendingMidTurnMsgs.length>0,q=this.proc?.lastResult.is_error===!0,L=this.proc?.lastResult.subtype??"success",P=typeof X?.error==="string"&&X.error.trim()?X.error.trim():L,R,O=!1,j=this.proc?this.backendLabel(this.proc.provider):this.backendLabel(),D=[G,_].filter(Boolean).join(";")||null;if(D)R=`⚠️ ${D}`,O=!0;else if(B)R=q?`⚠️ ${j} ${P},用户已介入`:"\uD83D\uDCE8 转交新卡";else if(q)R=`⚠️ ${j} ${P}`,O=!0;if(this.openingTurnOwner)this.openingTurnOwner.terminalSuffix=R,this.openingTurnOwner.terminalForcePush=O;if(D&&!this.currentTurn&&!this.openingTurn)C(this.chatId,`⚠️ ${D}`);if(A(`session "${this.sessionName}": SDK result subtype=${L} isError=${q} midBuffer=${this.pendingMidTurnMsgs.length} forcePush=${O}`),this.closeTurnCard(R,{forcePush:O,hasFreshResult:!0}).catch((E)=>{A(`session "${this.sessionName}": result card close failed: ${F(E)}`)}),this.status="idle",B)this.drainMidTurnAndOpen().catch((E)=>{A(`session "${this.sessionName}": mid-turn drain failed: ${F(E)}`)})}),H("bg_task_started",(X)=>{let V=X.tool_use_id??this.lastMainTaskToolUseId??void 0;A(`session "${this.sessionName}": bg_task_started task=${X.task_id} type=${X.task_type??"-"} subagent=${X.subagent_type??"-"} toolUseId=${V?.slice(0,8)??"-"} desc=${(X.description??"").slice(0,40)}`),this.applyBgStore(r6(this.bgStore(),{...X,tool_use_id:V})),this.onBackgroundTaskChanged()}),H("bg_task_progress",(X)=>{this.applyBgStore(t6(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_updated",(X)=>{this.applyBgStore(s6(this.bgStore(),X)),this.onBackgroundTaskChanged()}),H("bg_task_settled",(X)=>{if(A(`session "${this.sessionName}": bg_task_settled task=${X.task_id} status=${X.status}`),this.applyBgStore($7(this.bgStore(),X)),this.onBackgroundTaskChanged(),$.provider==="claude"&&!this.currentTurn&&!this.openingTurn&&this.initCount>=1)this.bgResumePending=!0}),H("subagent_step",(X)=>{this.applyBgStore(J7(this.bgStore(),X.thread_id,X.item_id,X.tool,X.phase,X.brief)),this.onBackgroundTaskChanged()}),H("exit",({code:X,signal:V,expected:z})=>{if(A(`session "${this.sessionName}": ${$.provider} exited code=${X} signal=${V} expected=${z}`),this.stoppingProc===$||this.blockedProc===$){if(this.blockedProc===$){let L=$.conversationMaterializationFailure?.(),P=this.persistResumableSessionId(!1,$,!1),R=[L&&$.isConversationResumable?.()!==!0?`Codex 会话落盘确认失败: ${F(L)}`:null,P].filter(Boolean).join(";");if(R)C(this.chatId,`⚠️ 旧进程退出后的恢复状态收尾失败: ${R}`);this.discardPendingCodexTurnAnchors($,"blocked process finally exited")}A(`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)=>{A(`session "${this.sessionName}": cancel Agent runs after process exit failed: ${F(L)}`)});let G=this.backendLabel($.provider),_=`code=${X??"null"}, signal=${V??"null"}`,B=z?`\uD83D\uDED1 ${G} 已退出`:`⚠️ ${G} 异常退出 (${_})`;if(this.currentTurn)this.closeTurnCard(B).catch((L)=>{A(`session "${this.sessionName}": process-exit current main-card close failed: ${F(L)}`)});let q=this.waitForTurnCloses().catch((L)=>{A(`session "${this.sessionName}": process-exit main-card close failed: ${F(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([q,this.resetBackgroundTasks()]);for(let P of L)if(P.status==="rejected")A(`session "${this.sessionName}": process-exit terminal cleanup failed: ${F(P.reason)}`);if(!z)await T(this.chatId,`⚠️ ${G} 异常退出 (${_})。回复任意消息将重新启动。`)}).catch((L)=>{A(`session "${this.sessionName}": process-exit cleanup rejected: ${F(L)}`)})})}accumulateResultStats(){let $=this.proc?.lastResult;if(!$)return;let Z=this.currentTurnUsageBaselineKnown?v6(this.proc?.lastTotalUsage,this.currentTurnUsageBaseline):this.proc?.provider==="claude"&&$.usage?{...$.usage}:null;this.lastTurnUsage=Z,this.currentTurnUsageBaseline=null,this.currentTurnUsageBaselineKnown=!1;let J=h6(Z),Y=this.proc?.provider==="claude"?0:$.cost_delta_usd??0,Q=$.duration_ms??0;if(J!=null)this.cumStats.tokens+=J;this.cumStats.costUsd+=Y,this.cumStats.turns+=$.num_turns??1,this.lastTurnDelta={tokens:J,costUsd:Y,durationMs:Q}}currentContextTokens($=this.proc){if($?.provider==="claude")return $.lastContextTokens??null;let Z=$?.lastUsage;return o4(Z)}contextLimitForDisplay($=this.proc){return r4($?.lastContextWindow)}async drainMidTurnAndOpen(){if(this.pendingMidTurnMsgs.length===0)return;let $=this.proc,Z=this.procEpoch;if(!$?.isAlive())return;if(!await this.waitForTurnOpenSlot($,Z))return;if(this.currentTurn||this.openingTurn||this.pendingMidTurnMsgs.length===0)return;let J;try{J=this.beginTurnOpen($,Z)}catch(Q){A(`session "${this.sessionName}": mid-turn open ownership conflict: ${F(Q)}`);return}let Y=this.pendingMidTurnMsgs;this.pendingMidTurnMsgs=[];try{for(let V of Y)if(this.pendingTurnInputs.push(V.text),V.msgId){let z=this.pendingReactionIds.get(V.msgId)??"";this.currentBatchReactionIds.set(V.msgId,z),this.pendingReactionIds.delete(V.msgId)}let Q=Y.map((V)=>V.wireText).join(`
189
+
190
+ `),H=Y[Y.length-1]?.userOpenId??this.lastUserOpenId,X=await this.openTurnCard(J,H,"user_message");if(!X||this.currentTurn!==X){for(let V of Y){if(!V.msgId)continue;let z=this.currentBatchReactionIds.get(V.msgId);if(this.currentBatchReactionIds.delete(V.msgId),z)j0(V.msgId,z)}this.status="idle";return}if(this.proc!==$||this.procEpoch!==Z||!$.isAlive()){await this.closeTurnCard(`⚠️ ${this.backendLabel($.provider)} 已退出`);for(let V of Y){if(!V.msgId)continue;let z=this.currentBatchReactionIds.get(V.msgId);if(this.currentBatchReactionIds.delete(V.msgId),z)j0(V.msgId,z)}this.status="stopped";return}try{this.sendClaimedUserText($,Q)}catch(V){A(`session "${this.sessionName}": mid-turn sendUserText failed after card open: ${V}`),await this.closeTurnCard(`❌ ${this.backendLabel($.provider)} 接收消息失败`),await C(this.chatId,`❌ ${this.backendLabel($.provider)} 接收消息失败: ${F(V)}。这批消息未开始处理,请重发。`),this.status="idle";return}this.status="working"}finally{if(this.releaseTurnOpen(J),!this.currentTurn&&this.pendingMidTurnMsgs.length>0&&this.proc===$&&this.procEpoch===Z&&$.isAlive())this.drainMidTurnAndOpen()}}async terminalizeSupersededCard($,Z,J){let Y=J?await R0($,M.footer,this.footerElement(Z)):!0;A0($);let Q=await _0($,z$({suffix:Z}));if(Y&&Q){await C0($);return}let W=`footer=${Y?"ok":"MISS"}, settings=${Q?"ok":"MISS"}`;A(`session "${this.sessionName}": superseded card terminal transaction incomplete card=${$.slice(0,12)} ${W}`),await C(this.chatId,`⚠️ 已作废卡片未能正常关闭 (${W})。`)}rebuildBackgroundAfterTurnOpenFailure(){if(!this.pendingRebuildBackgroundCard)return;if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length===0)return;this.openBackgroundCard().catch(($)=>{A(`session "${this.sessionName}": background rebuild after turn-open failure failed: ${F($)}`)})}async openTurnCard($,Z,J,Y={}){if(!this.ownsTurnOpen($))return null;if(this.bgResumePending=!1,this.backgroundCard&&g$(this.backgroundTasks))try{await this.migrateBackgroundCard(),this.pendingRebuildBackgroundCard=!0}catch(L){A(`session "${this.sessionName}": background migrate failed (non-blocking): ${L}`),this.startBackgroundRefreshTick(),this.scheduleBackgroundRefresh()}if(!this.ownsTurnOpen($))return null;let Q=++this.turnCounter,W=this.pendingTurnInputs;this.pendingTurnInputs=[],this.lastTurnUserPreview=W[0]?.slice(0,80)??this.lastTurnUserPreview,A(`session "${this.sessionName}": openTurnCard turn=${Q} trigger=${J} inputs=${W.length}`);let H=this.runtimeModelSelection(),X=this.withModel(Y.initialFooter??"Waiting...(0s)",H),V=$9({sessionName:this.sessionName,turn:Q,provider:H.provider,model:H.model??void 0,effort:H.effort,kind:J,userInputs:W,initialFooter:X,directStart:Y.directStart}),z=await i(this.chatId,V);if(!z){if(!this.ownsTurnOpen($))return null;if(A(`session "${this.sessionName}": openTurnCard sendCard EXHAUSTED retries — surfacing via raw text`),J==="user_message")await C(this.chatId,`❌ 创建对话卡片失败 (Feishu SDK 重试 3 次后仍连不上)。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);return this.rebuildBackgroundAfterTurnOpenFailure(),null}let G;try{G=await t0(z)}catch(L){if(A(`session "${this.sessionName}": id_convert failed: ${L}`),J==="user_message"&&this.ownsTurnOpen($))await C(this.chatId,`❌ 对话卡片初始化失败。你这条消息尚未送给 ${this.backendLabel()},请稍后重发。`);if(this.ownsTurnOpen($))this.rebuildBackgroundAfterTurnOpenFailure();return null}let _=(J==="bg_task_resume"||J==="scheduled_wakeup"?1:0)+(W.length>0?1:0)+1;if(!this.ownsTurnOpen($))return p0(G,_),await this.terminalizeSupersededCard(G,"⚠️ 会话已切换,本卡已作废",!0),null;let B={cardId:G,...H,messageId:z,userOpenId:Z,trigger:J,toolCount:0,toolByUseId:new Map,planSteps:[],planExplanation:null,planUpdateCount:0,goalUpdateCount:0,contextCompactCount:0,contextCompactionPending:new Map,contextCompactionCompleted:new Set,contextCompactionCompleting:new Set,contextCompactionEndOnly:new Map,lastContextCompactionCompletedAt:0,lastContextCompactionWasAnonymous:!1,toolBatches:new Map,openBatchI:null,taskCreateI:null,taskUpdateI:null,taskBoardResetThisTurn:!1,taskLiveInserted:!1,planLiveInserted:!1,assistantSegmentCount:0,currentAssistantSegmentId:null,currentAssistantText:"",segmentTexts:new Map,startedAt:Date.now(),footerStatusHandle:null,footerStatusStartedAt:0,footerStatusLabel:null,rotating:null,rotateCount:0,failureRotateCount:0,cardCapacityFailures:new Map,cardWriteFailureNotices:new Set,cardRotationFailed:!1,outboundSeenPaths:new Set,outboundSentPaths:new Set};if(p0(G,_,(L,P)=>{this.onCardWriteFailure(B,G,L,P)}),this.currentTurn=B,Y.startThinking!==!1)this.startThinkingFooter(B);if($.pendingCompactions.length>0){let L=$.pendingCompactions.splice(0);A(`session "${this.sessionName}": replay ${L.length} context compaction event(s) buffered during card open`);for(let P of L)this.handleContextCompacted(P)}let q=this.takeOrphanAssistantText();if(q)this.appendAssistant(q),this.finalizeCurrentAssistantSegment();if(this.pendingRebuildBackgroundCard){if(this.pendingRebuildBackgroundCard=!1,this.backgroundTasks.length>0)this.openBackgroundCard().catch((L)=>{A(`session "${this.sessionName}": background rebuild failed: ${F(L)}`)})}return B}maybeMidTurnRotate(){let $=this.currentTurn;if(!$)return;if($.rotating)return;if(!$.cardRotationFailed&&e7($.cardId)<YB)return;this.startMidTurnRotate($)}onCardWriteFailure($,Z,J,Y){let Q=this.currentTurn;if(Q!==$){A(`session "${this.sessionName}": ignore stale card failure card=${Z.slice(0,12)} code=${J??"n/a"} (turn owner changed)`);return}if(Q.cardId!==Z){A(`session "${this.sessionName}": ignore retired-card failure card=${Z.slice(0,12)} current=${Q.cardId.slice(0,12)} code=${J??"n/a"}`);return}if(Q.rotating)return;if(Q.cardRotationFailed)return;if(!s7(J,Y)){let H=Y?.operation??"unknown operation",X=Y?.elementId?` element=${Y.elementId}`:"";A(`session "${this.sessionName}": non-capacity card write failure card=${Z.slice(0,12)} operation=${H}${X} code=${J??"n/a"} — not rotating`);let V=`${Z}:${H}:${Y?.elementId??""}:${J??"MISS"}`;if(!Q.cardWriteFailureNotices.has(V))Q.cardWriteFailureNotices.add(V),C(this.chatId,`⚠️ 对话卡片有一项写入失败(code=${J??"MISS"}, ${H}${X})。未识别为卡片容量超限,未自动换卡;其余输出继续处理。`);return}let W=Y?.capacityFingerprint;if(W){let H=Q.cardCapacityFailures.get(W);if(H!==void 0){if(A(`session "${this.sessionName}": unchanged content still exceeds card capacity card=${Z} operation=${Y.operation} element=${Y.elementId??"MISS"} code=${J??"MISS"}`),!H)Q.cardCapacityFailures.set(W,!0),C(this.chatId,`⚠️ 有一项内容换卡后仍超出飞书容量,写入失败(code=${J??"MISS"}, ${Y.operation}, element=${Y.elementId??"MISS"});其余输出继续处理。`);return}Q.cardCapacityFailures.set(W,!1)}A(`session "${this.sessionName}": confirmed card capacity limit (${J}) on card=${Q.cardId.slice(0,8)}… — rotating to fresh card`),Q.failureRotateCount++,this.startMidTurnRotate(Q)}startMidTurnRotate($){if($.rotating)return;$.rotateCount++;let{cardId:Z,toolByUseId:J,toolBatches:Y}=$,Q={value:null},W=(H,X)=>{if(!Q.value)Q.value={code:H,failure:X}};$.rotating=(async()=>{try{A(`session "${this.sessionName}": mid-turn rotate triggered card=${Z.slice(0,8)}… elementCount=${e7(Z)}`);let H=$9({sessionName:this.sessionName,turn:this.turnCounter,provider:$.provider,model:$.model??void 0,effort:$.effort,kind:"card_full",userInputs:[]}),X=await i(this.chatId,H);if(!X){if(A(`session "${this.sessionName}": mid-turn rotate sendCard failed — retry on the next content event`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($);await C(this.chatId,"⚠️ 续卡发送失败,后续内容到达时会再次尝试。");return}let V;try{V=await t0(X)}catch(P){if(A(`session "${this.sessionName}": mid-turn rotate id_convert failed: ${P}`),this.currentTurn===$)$.cardRotationFailed=!0,this.stopFooterStatus($),await C(this.chatId,"⚠️ 续卡已发送,但 Card Kit 初始化失败;后续内容到达时会再次尝试。");return}p0(V,2,(P,R)=>{if($.rotating){W(P,R);return}this.onCardWriteFailure($,V,P,R)});let z=$.assistantWriteInflight?.get(Z);if(z?.size)await Promise.allSettled([...z]);this.stopFooterStatus($),$.cardId=V,$.cardRotationFailed=!1,$.messageId=X,$.toolCount=0,$.toolByUseId=new Map,$.toolBatches=new Map,$.openBatchI=null,$.planUpdateCount=0,$.goalUpdateCount=0;let G=$.currentAssistantSegmentId,_=$.currentAssistantText??"",B=$.segmentTexts;if($.assistantSegmentCount=0,$.currentAssistantSegmentId=null,$.currentAssistantText="",$.segmentTexts=new Map,G&&_){let P=M.assistant($.assistantSegmentCount++);$.currentAssistantSegmentId=P,$.currentAssistantText=_,$.segmentTexts.set(P,_)}if(_)this.startWritingFooter($);else this.startThinkingFooter($);if($.taskLiveInserted)X0($.cardId,Z1(this.taskBoard),{type:"insert_before",targetElementId:M.footer});if($.planLiveInserted)X0($.cardId,y2($.planSteps,$.planExplanation,M.planLive),{type:"insert_before",targetElementId:$.taskLiveInserted?M.taskBoardLive:M.footer});for(let P of $.contextCompactionPending.values()){if(P.cardId!==Z)continue;P.cardId=V,P.created=!1,P.createFailure=void 0;let R=M.contextCompact(P.i);P.createPromise=n4(V,S2(P.i,P.notice,R),{type:"insert_before",targetElementId:K0($)}).then((O)=>{if(P.cardId===V)P.created=O.landed,P.createFailure=O.failure;return O.landed})}for(let[P,R]of B){if(G&&_&&P===G)continue;if(!C1(Z,P))continue;let O=$.assistantSegmentCount++,j=M.assistant(O);$.segmentTexts.set(j,R),await this.addCompletedAssistantSegment($,j,R)}_5(this,Z,V,J,Y,$),await b0(Z),_5(this,Z,V,J,Y,$);let q=new Set([M.taskBoardLive,M.planLive,...[...$.contextCompactionPending.values()].map((P)=>M.contextCompact(P.i))]);if(G)q.add(G);for(let P of J.values())if(P.output==null)q.add(M.tool(P.i));if($J(Z).some((P)=>!q.has(P)))$.cardCapacityFailures.clear();await b0(V);try{let P=$.mathRenderInflight?.get(Z);if(P?.size)await Promise.allSettled([...P]);await b0(Z);let R=$.mathRendered?.get(Z);for(let[E,x]of B){if(G&&_&&E===G)continue;if(C1(Z,E))continue;if(R?.has(E))continue;await n(Z,E,this.completedAssistantElement(E,x))}let O=$.contextCompactCount>0?` · \uD83D\uDEA8 压缩×${$.contextCompactCount}`:"",j=await R0(Z,M.footer,this.footerElement(this.withModel(`\uD83D\uDCE8 已续至下一张卡 ↓${O}`)),{notifyCardFailure:!1});A0(Z);let D=await _0(Z,z$({suffix:"\uD83D\uDCE8 转下一张"}));if(j&&D)await C0(Z);else A(`session "${this.sessionName}": rotate old-card terminal MISS footer=${j} settings=${D}`),await C(this.chatId,`⚠️ 上一张对话卡未能正常关闭 (footer=${j?"ok":"MISS"}, settings=${D?"ok":"MISS"}),本轮输出已续到新卡。`)}catch(P){A(`session "${this.sessionName}": mid-turn rotate close-old failed: ${P}`)}A(`session "${this.sessionName}": mid-turn rotate done old=${Z.slice(0,8)}… new=${V.slice(0,8)}…`)}finally{$.rotating=null;let H=Q.value;if(H&&this.currentTurn===$)this.onCardWriteFailure($,$.cardId,H.code,H.failure)}})()}addPlanSnapshotOnCurrentTurn(){let $=this.currentTurn;if(!$||$.planSteps.length===0)return;this.maybeMidTurnRotate();let Z=$.cardId,J=M.planUpdate($.planUpdateCount++);X0(Z,Q8($.planSteps,$.planExplanation,"",J),{type:"insert_before",targetElementId:K0($)})}addGoalUpdateOnCurrentTurn($){let Z=this.currentTurn;if(!Z)return;this.maybeMidTurnRotate();let J=M.goalUpdate(Z.goalUpdateCount++);X0(Z.cardId,W8($,J),{type:"insert_before",targetElementId:K0(Z)})}addGoalClearedOnCurrentTurn(){let $=this.currentTurn;if(!$)return;this.maybeMidTurnRotate();let Z=M.goalUpdate($.goalUpdateCount++);X0($.cardId,{tag:"markdown",element_id:Z,content:`**\uD83C\uDFAF 当前目标**
191
+
192
+ 已清除`},{type:"insert_before",targetElementId:K0($)})}handleContextCompacted($){let Z=fW($);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;A(`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<Y6){A(`session "${this.sessionName}": late anonymous manual compaction duplicate ignored`);return}let J=this.currentTurn,Y=$.itemId?`item:${$.itemId}`:void 0,Q=Z.find((j)=>j.startsWith("turn:")),W=Y??Q,H=W?this.contextCompactionReceipts.get(W):void 0;if(Y&&!H&&$.phase!=="start"&&Q){let j=this.contextCompactionReceipts.get(Q);if(!j?.hasItemAlias&&j?.completed&&Date.now()-j.completedAt<Y6||!j?.hasItemAlias&&j?.completionKey&&J?.contextCompactionCompleting.has(j.completionKey))W=Q,H=j,j.hasItemAlias=!0,this.contextCompactionReceipts.delete(Y),this.contextCompactionReceipts.set(Y,j)}if(!J){if(this.openingTurnOwner?.backendTurnStarted){this.openingTurnOwner.pendingCompactions.push($),A(`session "${this.sessionName}": buffer context compaction ${$.phase??"event"} while turn card opens`);return}if(Z.length>0)this.rememberContextCompactionReceipt(Z,null,$.phase!=="start");A(`session "${this.sessionName}": context compaction ${$.phase??"event"} with no current turn thread=${$.threadId??"-"} turn=${$.turnId??"-"} item=${$.itemId??"-"}`);return}if(W&&H?.completed){A(`session "${this.sessionName}": duplicate context compaction ${$.phase??"event"} ignored receipt=${W}`);return}let X=this.contextCompactionOwnerId(J);if(W&&H&&H.ownerId!==X){this.rememberContextCompactionReceipt(Z,null,!0),A(`session "${this.sessionName}": late context compaction ${$.phase??"event"} ignored receipt=${W} (turn owner changed)`);return}if(W&&H?.completionKey&&J.contextCompactionCompleting.has(H.completionKey)){A(`session "${this.sessionName}": context compaction alias already writing receipt=${W}`);return}if($.phase!=="start"&&Z.length>0&&J.contextCompactionPending.size===0&&J.contextCompactionCompleting.has("__anonymous__")){A(`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<Y6){A(`session "${this.sessionName}": identified context compaction duplicate ignored after anonymous completion`);return}if($.phase==="start"){let j=tK($);if(J.contextCompactionPending.has(j)||J.contextCompactionCompleted.has(j)){A(`session "${this.sessionName}": duplicate context compaction start ignored key=${j}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();if(J.openBatchI=null,this.maybeMidTurnRotate(),J.lastContextCompactionWasAnonymous=!1,Z.length>0)this.rememberContextCompactionReceipt(Z,X,!1);let D=J.contextCompactCount++,E=J.cardId,x=M.contextCompact(D),b={i:D,cardId:E,notice:$,created:!1,createFailure:void 0,createPromise:Promise.resolve(!1)};b.createPromise=n4(E,S2(D,$,x),{type:"insert_before",targetElementId:K0(J)}).then((u)=>{if(b.cardId===E)b.created=u.landed,b.createFailure=u.failure;return u.landed}),J.contextCompactionPending.set(j,b),A(`session "${this.sessionName}": context compaction start #${D+1} key=${j}`),H$(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionCompleting.size>0){A(`session "${this.sessionName}": anonymous context compaction duplicate ignored while completion writes`);return}if(!$.itemId&&!$.turnId&&J.contextCompactionPending.size===0&&Date.now()-J.lastContextCompactionCompletedAt<Y6){A(`session "${this.sessionName}": immediate anonymous context compaction duplicate ignored`);return}let V=$.itemId||$.turnId;if(V&&J.contextCompactionCompleted.has(V)){A(`session "${this.sessionName}": duplicate context compaction completion ignored key=${V}`);return}let z=$.itemId?J.contextCompactionPending.has($.itemId)?$.itemId:null:sK(J),G=z?J.contextCompactionPending.get(z):void 0,_=z??V??"__anonymous__";if(J.contextCompactionCompleting.has(_)){A(`session "${this.sessionName}": context compaction completion already writing key=${_}`);return}if(this.startWorkingFooter(J),J.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();J.openBatchI=null,this.maybeMidTurnRotate();let B=eK(G?.notice,$),q=J.contextCompactionEndOnly.get(_),L=G?.i??q??J.contextCompactCount++;if(!G&&q===void 0)J.contextCompactionEndOnly.set(_,L);J.contextCompactionCompleting.add(_);let P=[...new Set([...fW(G?.notice??{}),...Z])];if(P.length>0)this.rememberContextCompactionReceipt(P,X,!1,_);let R=M.contextCompact(L),O=S2(L,B,R);A(`session "${this.sessionName}": context compaction completion write #${L+1} key=${_}`),(async()=>{let j=!1;if(!G)while(!0){let D=J.cardId;if(j=await M$(D,O,{type:"insert_before",targetElementId:K0(J)}),j)break;let E=J.rotating;if(E){await E;continue}if(J.cardId!==D)continue;break}else while(!0){let D=G.cardId;if(await G.createPromise,G.cardId!==D)continue;if(G.created)j=await R0(D,R,O);else{if(e3(G.createFailure?.code,G.createFailure))ZJ(D,R),j=await R0(D,R,O,{notifyCardFailure:!1});if(!j)j=await M$(D,O,{type:"insert_before",targetElementId:K0(J)})}if(G.cardId!==D)continue;if(j){G.created=!0;break}let E=J.rotating;if(E){await E;continue}if(G.cardId!==D)continue;break}if(J.contextCompactionCompleting.delete(_),!j){A(`session "${this.sessionName}": context compaction completion write MISS #${L+1} key=${_}`);return}if(z&&J.contextCompactionPending.get(z)===G)J.contextCompactionPending.delete(z);if(J.contextCompactionEndOnly.delete(_),_!=="__anonymous__")J.contextCompactionCompleted.add(_);if(J.lastContextCompactionCompletedAt=Date.now(),J.lastContextCompactionWasAnonymous=_==="__anonymous__",P.length>0){let D=[...this.contextCompactionReceipts.entries()].filter(([,E])=>E.completionKey===_).map(([E])=>E);this.rememberContextCompactionReceipt([...new Set([...P,...D])],null,!0)}A(`session "${this.sessionName}": context compaction completed #${L+1} key=${_}`)})().catch((j)=>{J.contextCompactionCompleting.delete(_),A(`session "${this.sessionName}": context compaction completion transaction failed: ${F(j)}`)}),H$(J.cardId,`\uD83D\uDEA8 压缩×${J.contextCompactCount}`)}contextCompactionOwnerId($){let Z=this.contextCompactionOwnerIds.get($);if(Z!==void 0)return Z;let J=++this.contextCompactionOwnerSequence;return this.contextCompactionOwnerIds.set($,J),J}rememberContextCompactionReceipt($,Z,J,Y){let Q={ownerId:J?null:Z,completed:J,completedAt:J?Date.now():0,...J||!Y?{}:{completionKey:Y},hasItemAlias:$.some((W)=>W.startsWith("item:"))};for(let W of $)this.contextCompactionReceipts.delete(W),this.contextCompactionReceipts.set(W,Q);while(this.contextCompactionReceipts.size>QB){let W;for(let H of this.contextCompactionReceipts.values()){if(H.completed){W=H;break}W??=H}if(!W)break;for(let[H,X]of this.contextCompactionReceipts)if(X===W)this.contextCompactionReceipts.delete(H)}}handleTurnPlanUpdated($){let Z=this.currentTurn;if(!Z){A(`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))A(`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?M.taskBoardLive:M.footer;Z.planLiveInserted=!0,X0(Z.cardId,y2(Z.planSteps,Z.planExplanation,M.planLive),{type:"insert_before",targetElementId:J})}else n(Z.cardId,M.planLive,y2(Z.planSteps,Z.planExplanation,M.planLive));this.addPlanSnapshotOnCurrentTurn()}handlePlanDelta($){if(typeof $.delta!=="string"||!$.delta){A(`session "${this.sessionName}": item/plan/delta missing delta text`);return}if(typeof $.itemId!=="string"||!$.itemId)A(`session "${this.sessionName}": item/plan/delta missing itemId`)}handleThreadGoalUpdated($){if(!$||typeof $.objective!=="string"){A(`session "${this.sessionName}": thread/goal/updated missing objective`);return}if($.tokenBudget!=null&&typeof $.tokenBudget!=="number")A(`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&&e4(Z)===e4(J))return;let Y=this.currentTurn;if(Y){if(this.startWorkingFooter(Y),Y.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();Y.openBatchI=null}this.addGoalUpdateOnCurrentTurn(J)}handleThreadGoalCleared(){if(!this.currentGoal)return;this.currentGoal=null;let $=this.currentTurn;if(!$)return;if(this.startWorkingFooter($),$.currentAssistantSegmentId)this.finalizeCurrentAssistantSegment();$.openBatchI=null,this.addGoalClearedOnCurrentTurn()}appendAssistant($){if(!this.currentTurn){if(this.openingTurn||this.bgResumeCardless)this.orphanAssistantCurrent+=$;return}let Z=this.currentTurn;if(this.startWritingFooter(Z),!Z.currentAssistantSegmentId){Z.openBatchI=null,this.maybeMidTurnRotate();let W=Z.assistantSegmentCount++,H=M.assistant(W);Z.currentAssistantSegmentId=H,Z.currentAssistantText=""}Z.currentAssistantText+=$;let J=Z.currentAssistantSegmentId;if(!J)return;Z.segmentTexts.set(J,Z.currentAssistantText),this.processOutboundMarkers(Z.currentAssistantText);let Q=this.cleanAssistantTextForDisplay(Z.currentAssistantText).slice(0,40);H$(Z.cardId,Q)}takeOrphanAssistantText(){let $=[...this.orphanAssistantSegments];if(this.orphanAssistantCurrent.trim())$.push(this.orphanAssistantCurrent);return this.orphanAssistantSegments=[],this.orphanAssistantCurrent="",$.join(`
193
+
194
+ `).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;A(`session "${this.sessionName}": flushing ${J.length} chars of orphan assistant text (${$})`),T(this.chatId,`\uD83D\uDCC4 后台轮输出(未能建卡,纯文本兜底):
195
+
196
+ ${J}`)}completedAssistantElement($,Z){if(Y5(Z))return this.mathAssistantContainer($,[{type:"markdown",text:Z}]);return{tag:"markdown",element_id:$,content:this.cleanAssistantTextForDisplay(Z).trim()||" "}}mathAssistantContainer($,Z){let J=Z.map((Y)=>Y.type==="markdown"?{tag:"markdown",content:this.cleanAssistantTextForDisplay(Y.text).trim()||" "}:{...Y.element});return{tag:"column_set",element_id:$,flex_mode:"none",columns:[{tag:"column",width:"weighted",weight:1,elements:J.length?J:[{tag:"markdown",content:" "}]}]}}async replaceSegmentWithMathImgs($,Z,J,Y){let Q=await mY(Y);if(!await R0(Z,J,this.mathAssistantContainer(J,Q.blocks),{notifyCardFailure:!1})){A(`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),A(`session "${this.sessionName}": math rendered ${J} (${Q.renderedImageCount} img, ${Q.blocks.length} blocks)`)}addCompletedAssistantSegment($,Z,J){let Y=$.cardId,Q=K0($),W=(async()=>{if(!await M$(Y,this.completedAssistantElement(Z,J),{type:"insert_before",targetElementId:Q}))return A(`session "${this.sessionName}": assistant segment ${Z} raw write failed on card=${Y}`),!1;if(Y5(J)){let X=this.replaceSegmentWithMathImgs($,Y,Z,J).catch((V)=>A(`session "${this.sessionName}": math render ${Z} failed: ${V}`));$.mathRenderInflight??=new Map,$.mathRenderInflight.get(Y)??$.mathRenderInflight.set(Y,new Set),$.mathRenderInflight.get(Y).add(X),X.finally(()=>$.mathRenderInflight?.get(Y)?.delete(X))}return!0})();return $.assistantWriteInflight??=new Map,$.assistantWriteInflight.get(Y)??$.assistantWriteInflight.set(Y,new Set),$.assistantWriteInflight.get(Y).add(W),W.finally(()=>$.assistantWriteInflight?.get(Y)?.delete(W)),W}async sendAssistantTextFallback($,Z){let J=$.trim();if(!J)return;let Y=`⚠️ 对话卡片正文写入失败(${Z}),以下为 agent 原始回复:
197
+
198
+ ${J}`;if(!await T(this.chatId,Y))A(`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 UY($))this.sendOutboundPath(Z,"send marker")}cleanAssistantTextForDisplay($){return d($)}sendOutboundPath($,Z){let J=w9($.trim());if(!J)return;let Y=this.currentTurn;if(Y?.outboundSeenPaths.has(J))return;if(Y?.outboundSeenPaths.add(J),!rK(J)){A(`session "${this.sessionName}": ignore non-absolute outbound path from ${Z}: ${J}`);return}Y?.outboundSentPaths.add(J),A(`session "${this.sessionName}": outbound send from ${Z}: ${J}`),o7(this.chatId,J)}startFooterStatus($,Z){if($.cardRotationFailed)return;let J=$.provider==="codex"?this.proc?.turnRetry:null;if(J)Z=J.phase==="waiting"?`⏳ 模型满载 · ${J.delayMs/1000}s 后重试 #${J.attempt}`:`⏳ 模型满载 · 正在重试 #${J.attempt}`;if($.footerStatusHandle&&$.footerStatusLabel===Z)return;this.stopFooterStatus($),$.footerStatusLabel=Z,$.footerStatusStartedAt=Date.now();let Y=()=>{if($.footerStatusLabel!==Z)return;let{label:W}=L$(Date.now()-$.footerStatusStartedAt,V1());this.replaceFooterContent($.cardId,this.withModel(`${Z} (${W})`))},Q=()=>{if($.footerStatusLabel!==Z)return;let{nextDelayMs:W}=L$(Date.now()-$.footerStatusStartedAt,V1());$.footerStatusHandle=setTimeout(()=>{Y(),Q()},Math.max(1,Math.ceil(W)))};Y(),Q()}startThinkingFooter($){this.startFooterStatus($,$B)}startWritingFooter($){this.startFooterStatus($,ZB)}startWorkingFooter($){this.startFooterStatus($,JB)}stopFooterStatus($){if(!$)return;if($.footerStatusHandle)clearTimeout($.footerStatusHandle);$.footerStatusHandle=null,$.footerStatusStartedAt=0,$.footerStatusLabel=null}async footerUsageSuffix($,Z,J,Y,Q){if(J&&(!Y||!Y.enabled||Y.agent!==$))return"";if(Y?.agent===$&&Y.enabled&&$==="claude"){let H=await Y.readUsage(),X=H.windows.find((z)=>z.kind==="fiveHour"),V=H.windows.find((z)=>z.kind==="weekly");if(X||V)return this.fmtDualWindowSuffix(X??null,V??null);return H.state==="ok"&&H.planLabel?` | ${H.planLabel}`:""}if($==="codex"){let H=Z?.isAlive()&&Z.provider==="codex"&&Z.readRateLimits?Z:null,V=(H?await jY(()=>H.readRateLimits()):null)??Q;return V?.state==="ok"?this.fmtDualWindowSuffix(V.fiveHour??null,V.weekly??null):""}let W=await r8();return W.state==="ok"?this.fmtDualWindowSuffix(W.fiveHour??null,W.weekly??null):""}fmtDualWindowSuffix($,Z){let J=(H)=>H.resetsAt&&H.resetsAt.getTime()>Date.now()?V$(H.resetsAt):"",Y=(H)=>{if(H?.percent==null)return null;let X=J(H);return X?`${X}·${Math.round(H.percent)}%`:`${Math.round(H.percent)}%`},Q=Y($),W=Y(Z);if(Q&&W)return` | ${Q}·[${W}]`;if(Q)return` | ${Q}`;if(W)return` | [${W}]`;return""}waitForTurnCloses(){let $=[...this.turnCloseInflight];if($.length===0)return Promise.resolve();return Promise.allSettled($).then((Z)=>{let J=Z.filter((Y)=>Y.status==="rejected").map((Y)=>Y.reason);if(J.length===1)throw J[0];if(J.length>1)throw AggregateError(J,`turn close failed: ${J.map(F).join("; ")}`)})}releaseTurnCloseReactions($){for(let[Z,J]of[...$.currentBatchReactionIds.entries(),...$.pendingReactionIds.entries()])if(J)j0(Z,J)}closeTurnCard($,Z={}){let J=this.currentTurn;if(!J)return this.waitForTurnCloses();if(!$&&J.cardRotationFailed)this.maybeMidTurnRotate();this.currentTurn=null,this.stopFooterStatus(J);let Y=this.proc,Q={turn:J,proc:Y,procEpoch:this.procEpoch,contextTokens:this.currentContextTokens(Y),contextLimit:this.contextLimitForDisplay(Y),lastTurnDelta:this.lastTurnDelta?{...this.lastTurnDelta}:null,lastTurnUsage:this.lastTurnUsage?{...this.lastTurnUsage}:null,tokenSourceId:this.selectedTokenSourceId,tokenSource:this.currentTokenSource(),codexUsage:PY(),currentBatchReactionIds:this.currentBatchReactionIds,pendingReactionIds:this.pendingReactionIds};this.currentBatchReactionIds=new Map,this.pendingReactionIds=new Map;let W=this.finishTurnCardClose(Q,$,Z).finally(()=>this.releaseTurnCloseReactions(Q));return this.turnCloseInflight.add(W),W.then(()=>{this.turnCloseInflight.delete(W)},()=>{this.turnCloseInflight.delete(W)}),W}async finishTurnCardClose($,Z,J={}){let{turn:Y}=$;if(Y.rotating)await Y.rotating;this.stopFooterStatus(Y);let Q=((Date.now()-Y.startedAt)/1000).toFixed(1),W=Y.cardId,H=Y.segmentTexts;await b0(W);let X=new Map;if(Y.currentAssistantSegmentId&&Y.currentAssistantText.trim()){let{currentAssistantSegmentId:D,currentAssistantText:E}=Y;if(!await this.addCompletedAssistantSegment(Y,D,E))X.set(D,E);Y.currentAssistantSegmentId=null,Y.currentAssistantText=""}let V=Y.assistantWriteInflight?.get(W);if(V?.size)await Promise.allSettled([...V]);let z=Y.mathRenderInflight?.get(W);if(z?.size)await Promise.allSettled([...z]);let G=Y.mathRendered?.get(W);for(let[D,E]of H){if(C1(W,D)){X.set(D,E);continue}if(G?.has(D))continue;await n(W,D,this.completedAssistantElement(D,E))}if(Y.cardRotationFailed)for(let[D,E]of H)X.set(D,E);let _=Z?Z:"✅",B=[`${_} ⏱ ${Q}s`];if(J.hasFreshResult){let{contextTokens:D,contextLimit:E}=$,x=Y.provider==="claude",b=J8(D,E,x?0:void 0);if(b)B.push(`\uD83E\uDDE0 ${b}`);let u=$.lastTurnDelta?.costUsd??0;if(u>0)B.push(`\uD83D\uDCB0 $${u.toFixed(3)}`)}if(Y.contextCompactCount>0)B.push(`\uD83D\uDEA8 压缩×${Y.contextCompactCount}`);if(Y.outboundSentPaths.size>0)B.push(`\uD83D\uDCCE ${Y.outboundSentPaths.size}`);let q=this.modelLine(Y);if(q)B.push(q);let L=B.join(" | "),P=J.hasFreshResult?Y8($.lastTurnUsage)+(Y.cardRotationFailed?"":await this.footerUsageSuffix(Y.provider,$.proc,$.tokenSourceId,$.tokenSource,$.codexUsage)):"",R=P?`${L}
199
+ ${P}`:L,O=await R0(W,M.footer,this.footerElement(R));A0(W);let j=await _0(W,z$({durationSec:Q,outputTokens:J.hasFreshResult?$.lastTurnUsage?.output_tokens:void 0,suffix:Z}));if(O&&j)await C0(W);else{let D=`footer=${O?"ok":"MISS"}, settings=${j?"ok":"MISS"}`;A(`session "${this.sessionName}": terminal card transaction incomplete card=${W.slice(0,12)} ${D}`),await C(this.chatId,`⚠️ 对话卡片终态写入失败 (${D})。本轮已结束: ${_}`)}for(let D of X.values())await this.sendAssistantTextFallback(D,"CardKit 元素未落地");if((J.forcePush||!Z)&&Y.userOpenId&&Y.messageId&&!Y.cardRotationFailed)n$(Y.messageId,[Y.userOpenId])}}});function v0($){return{card:{type:"raw",data:$}}}import{createServer as WB}from"node:http";import{randomUUID as HB}from"node:crypto";function uW($){if($.allowReply&&$.buttons?.length)throw Error(mW);let Z=$.level==="error"?"red":$.level==="warn"?"yellow":"blue",J=$.level==="error"?"❌":$.level==="warn"?"⚠️":"\uD83D\uDD14",Y=!!(($.buttons?.length||$.allowReply)&&$.notifyId),Q=new Date,W=`${String(Q.getHours()).padStart(2,"0")}:${String(Q.getMinutes()).padStart(2,"0")}`,H=[];for(let V of $.images??[])if(V.key)H.push({tag:"img",img_key:V.key,alt:{tag:"plain_text",content:"screenshot"}});else H.push({tag:"markdown",content:`<font color='red'>\uD83D\uDCF7 图片上传失败: ${V.src}</font>`});if(H.push({tag:"markdown",content:d6($.text??"")||"_(空消息)_"}),$.resolution){let V=$.resolution,z=V.kind==="text"?"已回复":`已选择:${V.text}`,G;if(V.status==="processing")G=`<font color='blue'>⏳ ${z} · 推送中…</font>`;else if(V.status==="failed")G=`<font color='red'>⚠️ ${V.kind==="text"?z:`已选:${V.text}`} · 回调失败:${d(V.detail??"未知")} · ${W}</font>`;else if(V.status==="delivered")G=`<font color='green'>✅ ${z} · 反馈已送达 · ${W}</font>`;else if(V.status==="unknown")G=`<font color='red'>⚠️ ${z} · ${V.kind==="text"?"送达状态未知,禁止自动重试":"外部回调已成功,但本地确认状态未知,禁止自动重试"} · ${W}</font>`;else G=`<font color='green'>✅ ${z} · ${W}</font>`;if(H.push({tag:"markdown",content:G}),V.status==="delivered"&&V.reply)H.push({tag:"markdown",content:d(V.reply)})}let X=Y&&(!$.resolution||$.resolution.status==="failed");if(X&&$.buttons?.length)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:$.buttons.map((V)=>({tag:"button",text:{tag:"plain_text",content:V.text},type:V.type,behaviors:[{type:"callback",value:{kind:"notify_callback",notify_id:$.notifyId,button_id:V.id}}]}))}]});if(H.push({tag:"hr"}),H.push({tag:"markdown",content:`<font color='grey'>via notify · ${W}</font>`}),X&&$.allowReply)H.push({tag:"column_set",columns:[{tag:"column",width:"weighted",weight:1,elements:[{tag:"button",text:{tag:"plain_text",content:"回复"},type:"primary",behaviors:[{type:"callback",value:{kind:"notify_reply",notify_id:$.notifyId}}]}]}]});return{schema:"2.0",config:Y?{update_multi:!0}:{},header:{title:{tag:"plain_text",content:`${J} ${$.title}`},template:Z},body:{elements:H}}}function x$($,Z,J){let Y=J?.status??Z.status,Q={waiting:"等待用户输入",sending:"正在发送回复",processing:"正在发送回复",delivered:"回复已送达",done:"回复已记录",failed:"回复发送失败",cancelled:"已取消回复",unknown:"回复送达状态未知"},W=[{tag:"markdown",content:`通知:${d($.title)}`}];if(Z.response)W.push({tag:"markdown",content:d(Z.response.text)});if(Y==="waiting")W.push({tag:"markdown",content:`<at id=${Z.openId}></at> 请在群里发送一条文字消息作为回复。
200
+ 你的下一条文字优先用于这条通知,完成后再回答 Agent 的提问。点击其他通知的「回复」会放弃本次回复;群控制命令仍然优先。`}),W.push({tag:"button",text:{tag:"plain_text",content:"取消回复"},type:"default",behaviors:[{type:"callback",value:{kind:"notify_reply_cancel",notify_id:$.notifyId,reply_id:Z.id}}]});if(Y==="cancelled"&&Z.cancelReason==="switched")W.push({tag:"markdown",content:"已切换到另一条通知,本次回复已放弃。"});let H=J?.detail??Z.error;if(H)W.push({tag:"markdown",content:`<font color='red'>${d(H)}</font>`});if(Y==="failed")W.push({tag:"markdown",content:"请点击原通知的「回复」按钮后重新输入。"});if(Y==="unknown")W.push({tag:"markdown",content:"无法确认是否已送达,请联系通知发起方核实;已禁止自动重试。"});if(J?.reply)W.push({tag:"markdown",content:d(J.reply)});return{schema:"2.0",config:{update_multi:!0},header:{title:{tag:"plain_text",content:Q[Y]},template:Y==="failed"||Y==="unknown"?"red":Y==="delivered"||Y==="done"?"green":"blue"},body:{elements:W}}}function GB($){if($===void 0||$===null)return{buttons:[]};if(!Array.isArray($))return{error:'"buttons" must be an array'};if($.length===0)return{buttons:[]};let Z=new Set,J=[];for(let Y of $){if(!Y||typeof Y!=="object")return{error:"each button must be an object"};let Q=String(Y.id??"").trim(),W=String(Y.text??"").trim();if(!zB.test(Q))return{error:`button id "${Q.slice(0,32)}" invalid (need ^[A-Za-z0-9_-]{1,64}$)`};if(!W)return{error:`button "${Q}" missing text`};if(W.length>IW)return{error:`button "${Q}" text > ${IW} chars`};if(Z.has(Q))return{error:`button id "${Q}" duplicated`};Z.add(Q);let H=String(Y.type??"default").toLowerCase(),X=VB.has(H)?H:"default";J.push({id:Q,text:W,type:X})}return{buttons:J}}function AB($){if($===void 0||$===null)return{};let Z=String($).trim();if(!Z)return{};let J;try{J=new URL(Z)}catch{return{error:`"callback" bad URL: "${Z.slice(0,64)}"`}}if(J.protocol!=="http:")return{error:`"callback" must be http (本机内), got "${J.protocol}"`};let Y=J.hostname.replace(/^\[|]$/g,"");if(Y!=="127.0.0.1"&&Y!=="localhost"&&Y!=="::1")return{error:`"callback" must be loopback (本机内), got "${J.hostname}"`};return{url:Z}}function pW($){try{let Z=WB((J,Y)=>{let Q=new URL(J.url??"/",`http://${J.headers.host??"localhost"}`);($.extraHandler?$.extraHandler(J,Y,Q).then((H)=>H?void 0:cW(J,Y)):cW(J,Y)).catch((H)=>{if(A(`notify: handler crash: ${H?.message??H}`),!Y.headersSent)Y.statusCode=500,Y.setHeader("content-type","text/plain; charset=utf-8"),Y.end("internal error");else try{Y.end()}catch{}})});Z.on("error",(J)=>{A(`notify: server bind failed (${$.bind}:${$.port}): ${J.message}`)}),Z.listen($.port,$.bind,()=>{A(`notify: HTTP listening at http://${$.bind}:${$.port}/notify`)})}catch(Z){A(`notify: server bind failed (${$.bind}:${$.port}): ${Z}`)}}async function cW($,Z,J=Z0){let Y=new URL($.url??"/",`http://${$.headers.host??"localhost"}`),Q=(U,y)=>{Z.statusCode=U,Z.setHeader("content-type","text/plain; charset=utf-8"),Z.end(y)},W=(U,y)=>{Z.statusCode=U,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(y))};if($.method==="GET"&&Y.pathname==="/")return Q(200,`lodestar notify
201
+ `+`POST /notify body={project,text,title?,level?,images?,buttons?,allow_reply?,callback?}push card to group
202
+ `+`GET /notify/result/<notify_id> → poll a button choice or text reply (pull mode, no callback server)
202
203
  `+`GET /agents/identities; POST/GET/DELETE /agents/runs[/<id>] → capability-protected delegated Agents
203
204
  `+`levels: info|warn|error (default info); images=[/abs/*.png] uploaded + embedded
204
- `+`buttons:[{id,text,type?}] (any count, one per row); callback=http://127.0.0.1:PORT/path optional (push) omit to poll
205
- `);if($.method==="GET"&&J.pathname.startsWith("/notify/result/")){let T=decodeURIComponent(J.pathname.slice(15)).trim();if(!T)return Y(400,"missing notify_id in path");let k=l6(T);if(!k)return Q(404,{error:"unknown notify_id",notify_id:T});return Q(200,TW(k))}if($.method!=="POST"||J.pathname!=="/notify")return Y(405,"use POST /notify");let W="";for await(let T of $)W+=T.toString();let H={};try{H=JSON.parse(W)}catch{return Y(400,"bad json")}let X=String(H.project??"").trim(),V=String(H.text??""),z=String(H.title??"").trim(),A=String(H.level??"info").toLowerCase();if(!X)return Y(400,'missing "project"');if(!V)return Y(400,'missing "text"');let{buttons:K,error:B}=o_(H.buttons);if(B)return Y(400,B);let{url:q,error:L}=r_(H.callback);if(L)return Y(400,L);let R=!!(K&&K.length),D=q??"",U=d_.has(A)?A:"info",P=z||X,j=M2(X),O=k1(j);if(!O)return G(`notify: project "${X}" (sanitized "${j}") has no chat binding → 404`),Y(404,`project "${X}" not bound — send any message in that Feishu group at least once after the daemon started, then retry`);let b=Array.isArray(H.images)?H.images:[],x=[];for(let T of b){let k=String(T??"").trim();if(!k)continue;let u=await w8(k);x.push({key:u??"",src:k})}let m=R?`nf_${i_()}`:"",h=SW({title:P,text:V,level:U,images:x,buttons:K,notifyId:m}),I=await i(O,h);if(!I)return G(`notify: sendCard failed → 502 (project="${X}" chat=${O.slice(0,8)}…)`),Y(502,"feishu sendCard failed (see daemon log)");if(R&&m){let T={notifyId:m,callbackUrl:D,chatId:O,messageId:I,project:X,title:P,text:V,level:U,imageKeys:x,buttons:K,createdAt:Date.now()};UW(T)}G(`notify: → ${X} (${O.slice(0,8)}…) level=${U} bytes=${V.length} images=${x.length} buttons=${K?.length??0} push=${R&&!!D?1:0} msg=${I}`),Q(200,{ok:!0,chat_id:O,message_id:I,...m?{notify_id:m}:{}})}function i6($,Z){return SW({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,notifyId:$.notifyId,resolution:Z})}var d_,n_,a_,NW=64;var D5=S(()=>{g();o();S$();P5();d_=new Set(["info","warn","error"]),n_=new Set(["default","primary","danger"]),a_=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as j5,readFileSync as M5,rmSync as t_}from"node:fs";import{homedir as d6}from"node:os";import{join as s$}from"node:path";function n6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){G(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[s$(d6(),".codex","skills"),s$(d6(),".claude","skills")];for(let Y of J){let Q=s$(Y,$.name,"SKILL.md");try{let W=j5(Q)?M5(Q,"utf8"):null;if(W===$.body)continue;h$(Q,$.body),G(`skill: ${W===null?"installed":"updated"} ${Q}`)}catch(W){G(`skill: sync failed (${Q}): ${W}`)}}if(!Z)s_($,x0)}function s_($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){G(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=s$(Z,".claude-plugin","plugin.json"),Y=s$(Z,"skills",$.name,"SKILL.md"),Q=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
206
- `;for(let[W,H]of[[J,Q],[Y,$.body]])try{let X=j5(W)?M5(W,"utf8"):null;if(X===H)continue;h$(W,H),G(`skill: ${X===null?"installed":"updated"} ${W}`)}catch(X){G(`skill: Claude plugin sync failed (${W}): ${X}`)}}function xW($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){G(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[s$(d6(),".codex","skills"),s$(d6(),".claude","skills")]).map((Q)=>s$(Q,$));if(!Z)Y.push(s$(x0,"skills",$));for(let Q of Y){let W=s$(Q,"SKILL.md");if(!j5(W))continue;try{let H=M5(W,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){G(`skill: obsolete path preserved because ownership is unclear ${W}`);continue}t_(Q,{recursive:!0,force:!1}),G(`skill: removed obsolete ${Q}`)}catch(H){G(`skill: obsolete removal failed (${Q}): ${H}`)}}}var F5=S(()=>{g();g$();R$()});function e_($){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`---
207
- name: ${CW}
208
- description: ${JSON.stringify(Z)}
205
+ card types: plain (neither field), selection (buttons), text reply (allow_reply:true); do not combine buttons and allow_reply:true
206
+ `+`all types support text + images; callback=http://127.0.0.1:PORT/path optional for selection/reply (push) omit to poll
207
+ `);if($.method==="GET"&&Y.pathname.startsWith("/notify/result/")){let U=decodeURIComponent(Y.pathname.slice(15)).trim();if(!U)return Q(400,"missing notify_id in path");let y=G$(U);if(!y)return W(404,{error:"unknown notify_id",notify_id:U});return W(200,oY(y))}if($.method!=="POST"||Y.pathname!=="/notify")return Q(405,"use POST /notify");let H="";for await(let U of $)H+=U.toString();let X={};try{X=JSON.parse(H)}catch{return Q(400,"bad json")}if(!X||typeof X!=="object"||Array.isArray(X))return Q(400,"body must be an object");if(X.allow_reply!==void 0&&typeof X.allow_reply!=="boolean")return Q(400,'"allow_reply" must be a boolean');let V=X.allow_reply===!0,z=String(X.project??"").trim(),G=String(X.text??""),_=String(X.title??"").trim(),B=String(X.level??"info").toLowerCase();if(!z)return Q(400,'missing "project"');if(!G)return Q(400,'missing "text"');let{buttons:q,error:L}=GB(X.buttons);if(L)return Q(400,L);let{url:P,error:R}=AB(X.callback);if(R)return Q(400,R);let O=!!(q&&q.length);if(O&&V)return Q(400,mW);let j=O||V,D=P??"",E=XB.has(B)?B:"info",x=_||z,b=J.sanitizeSessionName(z),u=J.chatIdForSession(b);if(!u)return A(`notify: project "${z}" (sanitized "${b}") has no chat binding → 404`),Q(404,`project "${z}" not bound send any message in that Feishu group at least once after the daemon started, then retry`);let g=Array.isArray(X.images)?X.images:[],c=[];for(let U of g){let y=String(U??"").trim();if(!y)continue;let w=await J.uploadImageKey(y);c.push({key:w??"",src:y})}let S=j?`nf_${HB()}`:"",k=uW({title:x,text:G,level:E,images:c,buttons:q,allowReply:V,notifyId:S}),h=await J.sendCard(u,k);if(!h)return A(`notify: sendCard failed → 502 (project="${z}" chat=${u.slice(0,8)}…)`),Q(502,"feishu sendCard failed (see daemon log)");if(j&&S){let U={notifyId:S,callbackUrl:D,chatId:u,messageId:h,project:z,title:x,text:G,level:E,imageKeys:c,buttons:q,allowReply:V,createdAt:Date.now()};nY(U)}A(`notify: → ${z} (${u.slice(0,8)}) level=${E} bytes=${G.length} images=${c.length} buttons=${q?.length??0} allowReply=${V} push=${j&&!!D?1:0} msg=${h}`),W(200,{ok:!0,chat_id:u,message_id:h,...S?{notify_id:S}:{}})}function G1($,Z){return uW({title:$.title,text:$.text,level:$.level,images:$.imageKeys,buttons:$.buttons,allowReply:$.allowReply,notifyId:$.notifyId,resolution:Z})}var XB,VB,zB,IW=64,mW='"buttons" and "allow_reply":true are mutually exclusive; choose button selection or text reply';var Q6=N(()=>{I();s();y0();a2();XB=new Set(["info","warn","error"]),VB=new Set(["default","primary","danger"]),zB=/^[A-Za-z0-9_-]{1,64}$/});import{existsSync as f5,readFileSync as v5,rmSync as _B}from"node:fs";import{homedir as W6}from"node:os";import{join as e0}from"node:path";function H6($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){A(`skill: sync disabled, skip ${$.name}`);return}let J=Z??[e0(W6(),".codex","skills"),e0(W6(),".claude","skills")];for(let Y of J){let Q=e0(Y,$.name,"SKILL.md");try{let W=f5(Q)?v5(Q,"utf8"):null;if(W===$.body)continue;g0(Q,$.body),A(`skill: ${W===null?"installed":"updated"} ${Q}`)}catch(W){A(`skill: sync failed (${Q}): ${W}`)}}if(!Z)KB($,w$)}function KB($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){A(`skill: sync disabled, skip Claude plugin ${$.name}`);return}let J=e0(Z,".claude-plugin","plugin.json"),Y=e0(Z,"skills",$.name,"SKILL.md"),Q=JSON.stringify({name:"lodestar-managed",description:"Lodestar daemon-managed Skills for Claude Agent SDK sessions",version:"1.0.0",author:{name:"Lodestar"}},null,2)+`
208
+ `;for(let[W,H]of[[J,Q],[Y,$.body]])try{let X=f5(W)?v5(W,"utf8"):null;if(X===H)continue;g0(W,H),A(`skill: ${X===null?"installed":"updated"} ${W}`)}catch(X){A(`skill: Claude plugin sync failed (${W}): ${X}`)}}function lW($,Z){if(process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"){A(`skill: sync disabled, skip removal ${$}`);return}let Y=(Z??[e0(W6(),".codex","skills"),e0(W6(),".claude","skills")]).map((Q)=>e0(Q,$));if(!Z)Y.push(e0(w$,"skills",$));for(let Q of Y){let W=e0(Q,"SKILL.md");if(!f5(W))continue;try{let H=v5(W,"utf8");if(!(H.includes(`name: ${$}`)||H.includes(`name: "${$}"`))){A(`skill: obsolete path preserved because ownership is unclear ${W}`);continue}_B(Q,{recursive:!0,force:!1}),A(`skill: removed obsolete ${Q}`)}catch(H){A(`skill: obsolete removal failed (${Q}): ${H}`)}}}var h5=N(()=>{I();I0();L0()});function BB($){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`---
209
+ name: ${iW}
210
+ 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.")}
209
211
  ---
210
212
 
211
213
  # feishu-notify
@@ -215,6 +217,22 @@ daemon. The daemon binds each group to a project name (= group name);
215
217
  once the daemon has seen at least one inbound message in that group,
216
218
  \`POST /notify\` with the project name routes a card to it.
217
219
 
220
+ ## Three card types
221
+
222
+ Choose exactly one interaction type. All three support the same markdown
223
+ \`text\` and optional local \`images\` paths for illustrated notifications.
224
+
225
+ | Type | Request fields | User controls |
226
+ |---|---|---|
227
+ | Plain notification | Omit \`buttons\`; omit \`allow_reply\` or set it to false | No buttons |
228
+ | Button selection | Supply nonempty \`buttons\`; omit \`allow_reply\` or set it to false | Only the caller-defined choice buttons |
229
+ | Custom text reply | Set \`allow_reply:true\`; omit \`buttons\` | One fixed 「回复」 button at the bottom |
230
+
231
+ Nonempty \`buttons\` and \`allow_reply:true\` cannot be combined; the
232
+ endpoint rejects that request with \`400\`. A \`callback\` URL by itself
233
+ does not add a reply button. Selection and custom-reply cards both
234
+ support push callbacks or pull results.
235
+
218
236
  ## Endpoint
219
237
 
220
238
  \`POST http://127.0.0.1:${$}/notify\` (loopback only)
@@ -229,16 +247,18 @@ Body (JSON):
229
247
  | \`level\` | | \`info\` (blue, default) / \`warn\` (yellow) / \`error\` (red) |
230
248
  | \`images\` | | Array of local image paths \`["/abs/a.png"]\` — uploaded to Feishu and embedded above the text (failed uploads surface inline in red, never dropped silently) |
231
249
  | \`buttons\` | | Array of \`{id, text, type?}\` — renders one button per row (vertical stack, any count). \`id\`: \`^[A-Za-z0-9_-]{1,64}$\`, unique. \`text\`: ≤ 64 chars (a short phrase is fine — each button owns its full row). \`type\`: \`default\` / \`primary\` / \`danger\` (default \`default\`). |
232
- | \`callback\` | | Optional loopback HTTP URL (e.g. \`http://127.0.0.1:9999/hook\`) **push mode**: on tap the daemon POSTs the choice here. Must be \`http://\` on \`127.0.0.1\` / \`localhost\` / \`::1\`. Omit for **pull mode** (see below). |
250
+ | \`allow_reply\` | | Boolean, default false. Selects the custom text reply type; cannot be combined with nonempty \`buttons\`. Only this type has a fixed 「回复」 button at the bottom. Clicking sends a separate 「等待用户输入」 card; the clicker's next text in that group is returned to the caller. |
251
+ | \`callback\` | | Optional loopback HTTP URL (e.g. \`http://127.0.0.1:9999/hook\`) — **push mode**: the daemon POSTs the button choice or submitted text here. Must be \`http://\` on \`127.0.0.1\` / \`localhost\` / \`::1\`. Omit for **pull mode** (see below). |
233
252
 
234
253
  Response: \`200 {ok, chat_id, message_id, notify_id?}\` (notify_id returned
235
- only when buttons are present) / \`400\` bad params / \`404\` group not
254
+ when buttons are present or allow_reply is true) / \`400\` bad params / \`404\` group not
236
255
  bound / \`502\` Feishu API rejected.
237
256
 
238
- \`GET /notify/result/<notify_id>\` — pull a button card's verdict with no
239
- callback server: \`{notify_id, project, message_id, resolved, button?,
240
- resolved_at?, resolved_by?}\`. \`resolved:false\` while pending. \`404\` on
241
- unknown notify_id.
257
+ \`GET /notify/result/<notify_id>\` — pull the verdict with no callback
258
+ server: \`{notify_id, project, message_id, resolved, unknown, button?,
259
+ response?, reply?, resolved_at?, resolved_by?}\`. \`resolved:false\` while
260
+ pending. \`unknown:true\` means delivery cannot be safely confirmed: do
261
+ not retry automatically. \`404\` on unknown notify_id.
242
262
 
243
263
  ## Usage — one-shot
244
264
 
@@ -363,8 +383,79 @@ Notes:
363
383
  - Registrations survive a daemon restart (persisted to
364
384
  \`~/.local/share/lodestar/notify-callbacks.json\`, pruned after 7 days).
365
385
 
386
+ ## Usage — receive a text reply
387
+
388
+ Set \`allow_reply:true\` and omit \`buttons\`. Use \`callback\` for
389
+ push, or omit it and poll the same result endpoint for pull.
390
+
391
+ \`\`\`bash
392
+ # desc: 发送允许用户输入文字回复的通知
393
+ curl -fsS -X POST http://127.0.0.1:${$}/notify \\
394
+ -H 'content-type: application/json' \\
395
+ -d '{"project":"ops","text":"请填写下一次部署时间",
396
+ "allow_reply":true,"callback":"http://127.0.0.1:9999/hook"}'
397
+ \`\`\`
398
+
399
+ Only this custom-reply card places 「回复」 at the bottom. Clicking it
400
+ sends a separate 「等待用户输入」 card mentioning the clicker. Their
401
+ next text message in the same group becomes the response. This new
402
+ card updates in place to show the entered text and delivery outcome;
403
+ the original notification also shows completion.
404
+
405
+ Text callback body (\`response\` replaces \`button\`):
406
+
407
+ \`\`\`json
408
+ {
409
+ "notify_id":"nf_...",
410
+ "message_id":"om_original_notification",
411
+ "chat_id":"oc_...",
412
+ "project":"ops",
413
+ "response":{
414
+ "type":"text",
415
+ "text":"明天上午十点",
416
+ "message_id":"om_user_message",
417
+ "prompt_message_id":"om_waiting_card"
418
+ },
419
+ "operator":{"open_id":"ou_..."},
420
+ "timestamp":1700000000
421
+ }
422
+ \`\`\`
423
+
424
+ In pull mode, the result contains the same \`response\`, plus
425
+ \`resolved:true\`, \`resolved_at\`, and \`resolved_by\`. While waiting,
426
+ \`reply.status\` is \`waiting\`; a failed delivery is \`failed\` with
427
+ \`reply.error\`. A callback can return the same optional acknowledgement
428
+ body described above; it is displayed on the receipt card. That body
429
+ is the script's acknowledgement, distinct from the user's response.
430
+
431
+ - Each group has one current notification reply. Clicking another
432
+ notification's 「回复」 abandons the previous waiting reply and updates
433
+ its card; only the newest clicker's input is accepted. Abandonment
434
+ does not POST an answer. Repeated clicks on the current reply do not
435
+ create duplicate waiting cards. A reply already sending cannot be switched.
436
+ - Plain text and text-only rich-text messages work. The current reply
437
+ takes precedence even if the message quotes an older card. Attachments
438
+ keep their normal route; group control commands retain priority.
439
+ - Text input priority is notification reply → Agent question → ordinary
440
+ Agent input. Agent questions wait while a notification reply is pending,
441
+ then resume after it ends. One question is answerable at a time; further
442
+ questions queue. An input is never submitted to two destinations.
443
+ - Only the current reply's clicker can submit or cancel it. A different
444
+ group member can select another notification's reply, replacing the
445
+ current waiting reply. Old cancel buttons cannot affect a newer attempt.
446
+ - The waiting card includes 「取消回复」. A click alone does not POST
447
+ anything. A completed custom-reply notification accepts one text response.
448
+ - Callback failure stays visible on the receipt; click 「回复」 on the
449
+ original card again to start a new attempt. No automatic resend.
450
+ - Waiting input survives daemon restart within the existing 7-day
451
+ registration retention. A restart during sending or a persistence
452
+ failure after external success marks the outcome \`unknown\` and
453
+ forbids automatic retry; verify delivery with the caller.
454
+
366
455
  ## Notes
367
456
 
457
+ - For free-text input, use \`allow_reply:true\` as above; do not manufacture
458
+ a caller-defined button named "reply" or ask users to type before clicking.
368
459
  - The group must have received at least one message after the daemon
369
460
  started (the daemon learns chat_id → name binding from inbound
370
461
  events). If you see \`404\` send any message in the group and retry.
@@ -372,13 +463,13 @@ Notes:
372
463
  Hand-edits will be overwritten — set
373
464
  \`LODESTAR_DISABLE_SKILL_SYNC=1\` and restart the daemon if you want
374
465
  to maintain the file yourself.
375
- `}function bW(){n6({name:CW,body:e_(v.notify.port)})}var CW="feishu-notify";var fW=S(()=>{U$();F5()});function $B(){return["---",`name: ${wW}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar. Delegated Agents and subagents must not use this Skill or delegate further. Main-Agent self-calls use native delegation capabilities.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Hard rule: native Agent capabilities for self-calls","","- For the main Agent only: when calling yourself or your own model/Agent, use your current"," Agent's native Agent/subagent capabilities. You MUST NOT use this Skill"," or the `lodestar-agent` command for self-calls.","- For example, Codex calling Codex uses Codex native subagents; Claude"," calling Claude uses Claude native Agent capabilities.","- This does not exempt delegated Agents from the single-level rule above.","- If native delegation is unavailable, report that limitation. It does not"," permit routing a self-call through this Skill.","","## Required workflow","","1. For another model/Agent, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon fans them out concurrently.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Continue the same native Agent session","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --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(`
376
- `)}function hW(){xW("lodestar-consult"),n6({name:wW,body:$B()})}var wW="lodestar-agent",vW;var U5=S(()=>{F5();vW=["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(`
377
- `)});function gW($){let Z=e($.identity.tokenSourceId);if(!Z)throw Error(`agent token source not found: ${$.identity.tokenSourceId}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`agent token source changed after identity discovery: ${Z.id}`);if(!$.identity.supportedEfforts.includes($.effort))throw Error(`${$.identity.displayName} does not support effort ${$.effort}`);let J=$.resumeSessionId?{kind:"resume",source:{provider:$.identity.provider,sessionId:$.resumeSessionId,cwd:$.workDir}}:{kind:"fresh"},{process:Y}=E4({provider:$.identity.provider,workDir:$.workDir,tokenSourceId:$.identity.tokenSourceId,model:$.identity.model,effort:$.effort,launch:J,developerInstructions:[$.developerInstructions,vW].filter(Boolean).join(`
466
+ `}function dW(){H6({name:iW,body:BB(v.notify.port)})}var iW="feishu-notify";var nW=N(()=>{U0();h5()});import{randomUUID as qB}from"node:crypto";function aW($){let Z=(W)=>W instanceof Error?W.message:String(W),J=(W,H,X)=>{if(!W)return"通知已过期或已移除";if(!X)return"无法识别回复人,操作未执行";if(H&&H!==W.chatId)return"通知不属于当前群,操作未执行";if(!W.allowReply)return"此通知未开启文字回复";if(W.unknownAt)return`回复送达状态未知,禁止自动重试:${W.unknownReason}`;if(W.resolvedAt)return"此通知已处理";if(u1(W.notifyId))return"通知正在处理中";return null},Y=async(W,H)=>{if($.log(`notify-reply: ${H}`),!await $.sendText(W,`❌ ${H}`))throw Error(`通知回复错误提示发送失败: ${H}`)},Q=async(W,H,X,V)=>{try{await $.updateCard(H,X)}catch(z){await Y(W.chatId,`${V},卡片更新失败:${Z(z)}`)}};return{async recover(W){let H=W.replyState;if(!H||!W.unknownAt)return;let X={kind:"text",status:"unknown",text:H.response?.text??"",operatorOpenId:H.openId,detail:W.unknownReason};await Q(W,H.promptMessageId,x$(W,H,X),"回复送达状态未知"),await Q(W,W.messageId,G1(W,X),"回复送达状态未知")},async open(W,H,X){let V=G$(W),z=J(V,H,X);if(z||!V)return{ok:!1,message:z};if(V.replyState?.status==="waiting"||V.replyState?.status==="sending")return{ok:!1,message:"此通知正在等待回复,请先在群里输入或由回复人取消"};let G=W5(V.chatId);if(G.some((_)=>_.replyState?.status==="sending"||u1(_.notifyId)))return{ok:!1,message:"上一条通知回复正在发送,请稍后切换"};l2(W);try{for(let q of G){let L={...q.replyState,status:"cancelled",cancelReason:"switched"};l1(q.notifyId,L),await Q(q,L.promptMessageId,x$(q,L),"已放弃上一条回复并切换通知")}let _={id:qB(),openId:X,promptMessageId:"",openedAt:Date.now(),status:"waiting"},B=await $.sendCard(V.chatId,x$(V,_));if(!B)return{ok:!1,message:"等待输入卡片发送失败,未开始接收回复,请重新点击「回复」"};_.promptMessageId=B;try{l1(W,_)}catch(q){let L=`等待输入状态保存失败,未开始接收回复:${Z(q)}`;return await Q(V,B,x$(V,_,{status:"failed",detail:L}),L),{ok:!1,message:L,presented:!0}}return{ok:!0,message:"等待输入卡片已发送,请在群里回复一条文字",presented:!0}}finally{i2(W),$.onWaitingChanged(V.chatId)}},async cancel(W,H,X,V){let z=G$(W),G=J(z,X,V);if(G||!z)return{ok:!1,message:G};let _=z.replyState;if(!_||_.id!==H||_.status!=="waiting")return{ok:!1,message:"此回复已结束或正在发送,无法取消"};if(_.openId!==V)return{ok:!1,message:"仅点击「回复」的人可以取消"};let B={..._,status:"cancelled"};return l1(W,B),$.onWaitingChanged(z.chatId),await Q(z,_.promptMessageId,x$(z,B),"回复已取消"),{ok:!0,message:"已取消回复",presented:!0}},async consume(W){let{chatId:H,openId:X,messageId:V,text:z,createTime:G}=W;if(!X||!V||!z.trim())return!1;if(aY(H,V))return!0;let _=d2(H,X);if(!_?.replyState)return!1;let B=_.replyState;if(G>0&&G<B.openedAt)return!1;if(B.status!=="waiting"||u1(_.notifyId))return await Y(H,"上一条通知回复正在发送,这条文字未提交,请稍后重发"),!0;let q={text:z,message_id:V,prompt_message_id:B.promptMessageId},L={...B,status:"sending",response:q};l2(_.notifyId);try{try{l1(_.notifyId,L)}catch(j){return await Y(H,`回复保存失败,尚未回传,请重新输入:${Z(j)}`),!0}let P;try{if(await $.updateCard(B.promptMessageId,x$(_,L)),_.callbackUrl)P=await $.dispatch(_,q,X);else n2(_.notifyId,void 0,X),P={ok:!0,detail:"已记录"}}catch(j){P={ok:!1,detail:Z(j)}}let R;if(P.ok){let j=_.callbackUrl?v9(_.notifyId,void 0,X):{state:"complete"};R={kind:"text",text:z,operatorOpenId:X,status:j.state==="unknown"?"unknown":_.callbackUrl?"delivered":"done",...j.state==="unknown"?{detail:j.detail}:{reply:P.reply}}}else{R={kind:"text",text:z,operatorOpenId:X,status:"failed",detail:P.detail};try{l1(_.notifyId,{...L,status:"failed",error:P.detail})}catch(j){let D=`${P.detail};失败状态保存失败:${Z(j)}`;try{H5(_.notifyId,void 0,X,D)}catch(E){$.log(`notify-reply: UNKNOWN persistence failed: ${Z(E)}`)}R={...R,status:"unknown",detail:D}}}let O=R.status==="delivered"?"回复已送达":R.status==="done"?"回复已记录":R.status==="unknown"?`回复送达状态未知:${R.detail}`:`回复未送达:${R.detail}`;return await Q(_,B.promptMessageId,x$(_,L,R),O),await Q(_,_.messageId,G1(_,R),O),$.log(`notify-reply: notify_id=${_.notifyId} status=${R.status}`),!0}finally{i2(_.notifyId),$.onWaitingChanged(_.chatId)}}}}var oW=N(()=>{a2();Q6()});function LB(){return["---",`name: ${rW}`,`description: ${JSON.stringify("Main Agents can delegate a task to a different configured model or Agent through Lodestar. Delegated Agents and subagents must not use this Skill or delegate further. Main-Agent self-calls use native delegation capabilities.")}`,"---","","# lodestar-agent","","Use Lodestar to call the Agent represented by a selected live identity.","Each identity resolves to its configured Token Source, provider Agent backend,","model, and effort. The caller-supplied prompt becomes that Agent run's task.","","## Single-level delegation","","- Only the main Agent may delegate work. If you are already a delegated"," Agent or subagent, complete your assigned task yourself: do not delegate further.","- This prohibition covers this Skill, `lodestar-agent run` / `follow-up`,"," native Agent/subagent tools, and delegation through provider CLIs or HTTP APIs.","- `LODESTAR_AGENT_ROLE=worker` identifies a Lodestar delegated process."," Native subagents are also delegated Agents even when they inherit a main role environment.","- Return additional work requests to the main Agent. It can assign separate"," tasks, continue your session, or answer your questions.","","## Hard rule: native Agent capabilities for self-calls","","- For the main Agent only: when calling yourself or your own model/Agent, use your current"," Agent's native Agent/subagent capabilities. You MUST NOT use this Skill"," or the `lodestar-agent` command for self-calls.","- For example, Codex calling Codex uses Codex native subagents; Claude"," calling Claude uses Claude native Agent capabilities.","- This does not exempt delegated Agents from the single-level rule above.","- If native delegation is unavailable, report that limitation. It does not"," permit routing a self-call through this Skill.","","## Required workflow","","1. For another model/Agent, query the live identity catalog immediately before"," every new task:","","```bash","# desc: 查询当前可用的 Agent 身份","lodestar-agent identities --json","```","",'2. Select only identities with `status: "ready"`. Never invent, cache,'," substitute, or silently downgrade an identity/model/effort.","3. Give the child the complete task, relevant context, authority boundaries,"," expected deliverable, and verification requirements in the raw prompt."," Explicitly tell it to complete the work itself without further delegation.","4. For the same prompt sent to several other models, pass every identity to one run"," with repeated `--identity`; the daemon fans them out concurrently.","5. Wait for the result. Attribute each result to its actual model and surface"," failures. Child file changes are live in the same workspace.","","## Run a task","","```bash","# desc: 把完整任务交给指定 Agent","lodestar-agent run --identity '<identity-id>' --stdin <<'EOF'","<raw task prompt written by the main Agent>","EOF","```","","## Continue the same native Agent session","","```bash","# desc: 在同一原生 Agent 会话中继续任务","lodestar-agent follow-up '<run-id>' --identity '<identity-id>' --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(`
467
+ `)}function sW(){lW("lodestar-consult"),H6({name:rW,body:LB()})}var rW="lodestar-agent",tW;var g5=N(()=>{h5();tW=["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(`
468
+ `)});function eW($){let Z=$0($.identity.tokenSourceId);if(!Z)throw Error(`agent token source not found: ${$.identity.tokenSourceId}`);if($.identity.spawnRevision&&Z.spawnRevision!==$.identity.spawnRevision)throw Error(`agent token source changed after identity discovery: ${Z.id}`);if(!$.identity.supportedEfforts.includes($.effort))throw Error(`${$.identity.displayName} does not support effort ${$.effort}`);let J=$.resumeSessionId?{kind:"resume",source:{provider:$.identity.provider,sessionId:$.resumeSessionId,cwd:$.workDir}}:{kind:"fresh"},{process:Y}=w4({provider:$.identity.provider,workDir:$.workDir,tokenSourceId:$.identity.tokenSourceId,model:$.identity.model,effort:$.effort,launch:J,developerInstructions:[$.developerInstructions,tW].filter(Boolean).join(`
378
469
 
379
- `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return ZB(Y,$.prompt,$.callbacks)}function ZB($,Z,J={},Y=UZ){let Q=[],W=null,H=!1,X=null,V=null,z=[],A,K,B=Date.now(),q=new Promise((E,y)=>{A=E,K=y}),L=(E)=>{if(!E)return null;try{return Y($.provider,E),J.onSession?.(E),null}catch(y){return y instanceof Error?y:Error(String(y))}},R=()=>{if($.off("assistant_text",U),$.off("tool_use",j),$.off("tool_result",O),$.off("subagent_step",b),$.off("can_use_tool",x),$.off("hook_callback",m),$.off("init",h),!$.isAlive())$.off("error",I);$.off("turn_retry",T),$.off("result",k),$.off("exit",u)},D=(E,y)=>{if(X)return X;return H=!0,z.length=0,X=Promise.resolve().then(async()=>{let f=L($.sessionId);try{await $.kill(3000)}catch(v$){V=v$ instanceof Error?v$:Error(String(v$))}R();let M$=[E,f,V].filter((v$)=>!!v$),W$=M$.length>1?AggregateError(M$,M$.map((v$)=>v$.message).join("; ")):M$[0];if(W$){K(new u2(W$,Q.join("").trim(),$.sessionId));return}let F$=$.sessionId;if(!F$){K(new u2(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let c5=Q.join("").trim(),r1=QB(y?.checkpoint,$);A({output:c5,outputTruncated:!1,sessionId:F$,...r1?{checkpointId:r1}:{},durationMs:Date.now()-B,usage:$.lastUsage?{...$.lastUsage}:null})}),X},U=(E)=>{if(H||E?.parentToolUseId||typeof E?.text!=="string")return;Q.push(E.text)},P=(E)=>{if(H)return;try{J.onProgress?.(E)}catch(y){D(y instanceof Error?y:Error(String(y)))}},j=(E)=>P({at:new Date().toISOString(),phase:"started",tool:String(E?.name??"tool"),detail:""}),O=(E)=>P({at:new Date().toISOString(),phase:"completed",tool:E?.is_error?"tool error":"tool result",detail:""}),b=(E)=>P({at:new Date().toISOString(),phase:E?.phase??"info",tool:String(E?.tool??"subagent"),detail:""}),x=(E)=>{if(H)return;if(E.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(E.request_id,"allow",{updatedInput:E.input??{}})}catch(f){D(f instanceof Error?f:Error(String(f)))}return}let y;try{y=JB(E)}catch(f){D(f instanceof Error?f:Error(String(f)));return}if(z.some((f)=>f.request.requestId===y.requestId))return;z.push({request:y,originalInput:E.input??{}});try{if(z.length===1)J.onNeedsInput?.(y)}catch(f){D(f instanceof Error?f:Error(String(f)))}},m=(E)=>{if(H)return;try{$.sendHookResponse(String(E.request_id),{})}catch(y){D(y instanceof Error?y:Error(String(y)))}},h=(E)=>{let y=L(E?.session_id??$.sessionId);if(y)D(y)},I=(E)=>{W=E instanceof Error?E:Error(String(E))},T=(E)=>{P({at:new Date().toISOString(),phase:"info",tool:"Codex 容量重试",detail:E.phase==="waiting"?`${E.message} · ${E.delayMs/1000}s 后重试 #${E.attempt}`:`正在重试 #${E.attempt}`})},k=(E)=>{let y=E?.is_error?Error(String(E.error??E.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;D(y,E)},u=(E)=>{if(H)return;let y=`code=${E?.code??"null"} signal=${E?.signal??"null"}`;D(W??Error(`delegated agent exited before result (${y})`))};$.on("assistant_text",U),$.on("tool_use",j),$.on("tool_result",O),$.on("subagent_step",b),$.on("can_use_tool",x),$.on("hook_callback",m),$.on("init",h),$.on("error",I),$.on("turn_retry",T),$.on("result",k),$.on("exit",u);try{$.sendInitialize(),$.sendUserText(Z)}catch(E){D(E instanceof Error?E:Error(String(E)))}return{done:q,isAlive:()=>$.isAlive(),pendingInput:()=>z[0]?.request??null,answer(E,y){let f=z[0];if(!f)throw Error("delegated agent is not waiting for input");if(f.request.requestId!==E)throw Error(`delegated agent input request mismatch: expected ${f.request.requestId}`);if($.sendPermissionResponse(E,"allow",{updatedInput:{...f.originalInput,answers:y}}),z.shift(),z[0])J.onNeedsInput?.(z[0].request)},async cancel(E="delegated agent cancelled"){let y=H;if(await D(Error(E)),await q.catch(()=>{}),y){if($.isAlive())await $.kill(3000);V=null,R()}if(V)throw V}}}function JB($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,W)=>YB(Q,W));if(Y.length===0)throw Error("delegated agent input request contains no questions");return{requestId:String($.request_id),...$.tool_use_id?{toolUseId:$.tool_use_id}:{},questions:Y}}function YB($,Z){let J=$&&typeof $==="object"?$:{question:$},Y=String(J.question??J.prompt??J.title??"").trim();if(!Y)throw Error(`delegated agent input question ${Z+1} is empty`);let Q=String(J.id??Y),W=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let X=H&&typeof H==="object"?H:{};return{label:String(X.label??X.value??""),...X.description?{description:String(X.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:W}}function QB($,Z){if(typeof $?.id==="string"&&$.id)return $.id;if(Z.provider==="codex"&&typeof Z.lastCompletedTurnId==="string"&&Z.lastCompletedTurnId)return Z.lastCompletedTurnId;if(Z.provider==="claude"&&Z.lastAssistantUuid)return Z.lastAssistantUuid;return}var u2;var IW=S(()=>{W8();z4();G$();U5();u2=class u2 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as WB,randomBytes as HB,randomUUID as XB}from"node:crypto";import{existsSync as VB,readdirSync as zB,readFileSync as aW}from"node:fs";import{join as o6}from"node:path";class E5{deps;runs=new Map;capabilities=new Map;activeTurns=0;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;constructor($=GB){this.deps=$;this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(mW);let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if($.kind!=="session")throw Error(mW);let Y=this.requireMutableDescendant($,Z);if(!l1(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=dW(Y.snapshot,J.identityId);if(Y.handles.get(Q.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Q.sessionId)throw Error(`${Q.identityName} has no resumable native session id`);let W=J.effort??Q.effort,H=this.reserveCapacity($,1);try{return await this.createRun($.session,{identityIds:[Q.identityId],prompt:J.prompt,effort:W},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeByIdentity:new Map([[Q.identityId,Q.sessionId]])})}finally{H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=dW(Y.snapshot,J.identityId);if(Q.status!=="needs_input"||!Q.pendingInput)throw Error(`${Q.identityName} is not waiting for input`);if(Q.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Q.pendingInput.requestId}`);let W=Y.handles.get(Q.identityId);if(!W)throw Error("waiting agent process is no longer alive; start a follow-up run");W.answer(J.requestId,J.answers);let H=W.pendingInput();if(Q.status=H?"needs_input":"running",H)Q.pendingInput=H;else delete Q.pendingInput;return delete Q.queuedReason,this.refreshNonterminalStatus(Y),this.persist(Y),await this.updateWorkerCard(Y,Q),p2(Y.snapshot)}getRun($,Z){return p2(this.requireAccessibleRun($,Z).snapshot)}async cancelRun($,Z,J="agent run cancelled"){let Y=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Y))return!1;return await this.cancelTree(Y,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Y=[...this.runs.values()].filter((W)=>W.snapshot.sessionName===$&&W.snapshot.chatId===Z&&!W.snapshot.parentRunId&&this.treeHasActiveRun(W)),Q=await Promise.allSettled(Y.map((W)=>this.cancelTree(W,J)));O5(Q)}async shutdown($){let Z=new Set([...this.runs.values()].map((H)=>`${H.snapshot.sessionName}\x00${H.snapshot.chatId}`));for(let H of Z){let[X,V]=H.split("\x00");this.bumpCancellationEpoch(X,V)}let J=[...this.runs.values()].filter((H)=>!H.snapshot.parentRunId&&this.treeHasActiveRun(H)),Y=await Promise.allSettled(J.map((H)=>this.cancelTree(H,$))),Q=[...this.runs.values()].flatMap((H)=>[...H.handles.values()]),W=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));O5([...Y,...W])}async createRun($,Z,J){this.pruneRuns();let Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let Q=this.deps.getCatalog(),W=Z.identityIds.map((q)=>{let L=Q.identities.find((R)=>R.id===q);if(!L)throw Error(`agent identity not found: ${q}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),H=W.map((q)=>AB(q,KB(q,Z.effort),J.resumeByIdentity?.get(q.id))),X=`agent_${XB()}`,V={runId:X,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:H,createdAt:new Date().toISOString()},z=await this.deps.sendCard($.chatId,k7(V));if(!z)throw Error("agent card creation failed; delegated agents were not started");let A;try{A=await this.deps.convertMessageToCard(z)}catch(q){throw await this.deps.sendTextRaw($.chatId,`❌ agent 卡片初始化失败,Agent 未启动: ${j$(q)}`),q}V.cardMessageId=z,this.deps.recordCardCreated(A,H.length+2,(q)=>{G(`agent: card write failed run=${X} code=${q??"MISS"}`)});let K={snapshot:V,session:$,cardId:A,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};if(this.runs.set(X,K),J.parentRunId)Y?.children.add(X);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){K.cancelled=!0;let q="任务已在启动前取消";for(let L of K.snapshot.workers)L.status="cancelled",L.error=q,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",q),p2(K.snapshot)}this.persist(K);for(let q of W){let L=J.resumeByIdentity?.get(q.id);this.executeWorker(K,q,Z.prompt,L).catch((R)=>{G(`agent: run=${X} worker=${q.id} crashed: ${j$(R)}`)})}return p2(V)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(()=>{Q.queuedReason=`等待执行名额(最多同时运行 ${cW} 个 Agent)`,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.add(Z.id),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let W="";try{if(W=HB(32).toString("base64url"),this.capabilities.set(W,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,W),Q.status="running",Q.startedAt=new Date().toISOString(),delete Q.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Q),$.cancelled)return;let H=this.deps.startWorker({identity:Z,effort:Q.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:qB(T1($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:x0},hostEnv:{LODESTAR_AGENT_URL:T4(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:W,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(V)=>{if($.cancelled)return;Q.status="needs_input",Q.pendingInput=V,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Q)},onProgress:(V)=>this.recordStep($,Q,V),onSession:(V)=>{if(Q.sessionId===V)return;Q.sessionId=V,this.persist($)}}});$.handles.set(Z.id,H);let X=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=X.output,Q.outputTruncated=X.outputTruncated,Q.sessionId=X.sessionId,Q.checkpointId=X.checkpointId,Q.durationMs=X.durationMs,Q.usage=X.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof u2){if(Q.output=H.output,Q.outputTruncated=!1,H.sessionId)Q.sessionId=H.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Q.status="failed",Q.error=j$(H),Q.finishedAt=new Date().toISOString(),Q.startedAt)Q.durationMs=Date.now()-Date.parse(Q.startedAt);delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(W)this.capabilities.delete(W);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||a6(Z.status))return;if(Z.steps.push(J),Z.steps.length>pW)Z.steps.splice(0,Z.steps.length-pW);if($.progressTimers.has(Z.identityId))return;let Y=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z)},250);$.progressTimers.set(Z.identityId,Y)}clearProgressTimer($,Z){let J=$.progressTimers.get(Z);if(J)clearTimeout(J);$.progressTimers.delete(Z)}refreshNonterminalStatus($){if($.cancelled)return;if($.snapshot.workers.some((Z)=>Z.status==="needs_input"))$.snapshot.status="needs_input";else if($.snapshot.workers.some((Z)=>Z.status==="running"))$.snapshot.status="running";else $.snapshot.status="queued";delete $.snapshot.finishedAt}recomputeRun($){if($.cancelled||$.finalized||$.finalizing)return;let Z=$.snapshot.workers;if(Z.some((Y)=>Y.status==="needs_input"||Y.status==="running"||Y.status==="queued")){this.refreshNonterminalStatus($),this.persist($);return}let J=Z.some((Y)=>Y.status==="failed")?"failed":"completed";this.finalizeRun($,J,J==="failed"?"一个或多个 Agent 失败":void 0).catch((Y)=>{$.finalizing=!1,$.finalized=!1,$.snapshot.status="failed",$.snapshot.error=`Agent terminal persistence failed: ${j$(Y)}`,G(`agent: terminal finalization failed run=${$.snapshot.runId}: ${j$(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${j$(Y)}`).catch((Q)=>G(`agent: terminal failure delivery failed: ${j$(Q)}`))})}async cancelTree($,Z){let J=!l1($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let W of[...$.progressTimers.keys()])this.clearProgressTimer($,W);for(let W of $.capabilityByIdentity.values())this.capabilities.delete(W);$.capabilityByIdentity.clear()}while(!0){let W=[...$.children].map((X)=>this.runs.get(X)).filter((X)=>!!X&&this.treeHasActiveRun(X));if(W.length===0)break;let H=await Promise.allSettled(W.map((X)=>this.cancelTree(X,Z)));if(Y.push(...H),H.some((X)=>X.status==="rejected"))break}if(!J){O5(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([W,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${W}: Agent process is still alive after cancellation`);$.handles.delete(W),this.releaseWorkerSlot($,W)}))),Y.some((W)=>W.status==="rejected")){let W=oW(Y);throw $.snapshot.status="failed",$.snapshot.error=W.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${W.message}`).catch((H)=>G(`agent: cancellation failure notice failed: ${j$(H)}`)),W}let Q=[];for(let W of $.snapshot.workers)if(!a6(W.status))W.status="cancelled",W.error=Z,W.finishedAt=new Date().toISOString(),delete W.pendingInput,Q.push(W);await Promise.all(Q.map((W)=>this.updateWorkerCard($,W))),await this.finalizeRun($,"cancelled",Z)}async finalizeRun($,Z,J){if($.finalized||$.finalizing)return;$.finalizing=!0;for(let Y of[...$.progressTimers.keys()])this.clearProgressTimer($,Y);if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)$.snapshot.error=J;try{if($.cardId){if(this.deps.cancelSummary($.cardId),await this.deps.flush($.cardId),!await this.deps.replaceElementChecked($.cardId,M.agentRunFooter,w2($.snapshot)))this.recordPresentationError($,"agent footer update MISS");if(!await this.deps.patchSettingsChecked($.cardId,{config:{streaming_mode:!1,summary:{content:v2($.snapshot)}}}))this.recordPresentationError($,"agent terminal settings update MISS");await this.deps.flush($.cardId),await this.deps.dispose($.cardId)}}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${j$(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,$.snapshot.presentationErrors?.length)await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ agent ${$.snapshot.runId} 结果已保存,但卡片有 ${$.snapshot.presentationErrors.length} 个呈现错误。`).catch((Y)=>G(`agent: warning delivery failed run=${$.snapshot.runId}: ${j$(Y)}`))}async updateWorkerCard($,Z){if(!$.cardId||$.finalized)return;try{if(!await this.deps.replaceElementChecked($.cardId,B6(Z.identityId),_6(Z,q6($.snapshot.workers.length),$.snapshot.workers.length===1)))this.recordPresentationError($,`agent worker card MISS: ${Z.identityName}`);if(!await this.deps.replaceElementChecked($.cardId,M.agentRunFooter,w2($.snapshot)))G(`agent: progress update MISS run=${$.snapshot.runId}; later updates will refresh it`);this.deps.patchSummaryThrottled($.cardId,v2($.snapshot))}catch(J){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${j$(J)}`)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,G(`agent: ${Z} run=${$.snapshot.runId}`)}persist($){if(!$.snapshot.promptArtifact)$.snapshot.promptArtifact=`${$.snapshot.runId}.prompt.txt`;this.persistTextArtifact($,$.snapshot.promptArtifact,$.snapshot.prompt);for(let J of $.snapshot.workers){if(!J.output)continue;if(!J.outputArtifact){let Y=WB("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=p2($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(o6(y0,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;rW(Z),this.deps.writeTextArtifact(o6(y0,Z),J),$.persistedArtifacts.add(Z)}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||$.snapshot.workDir!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!l1($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Y=[...this.runs.values()].filter((X)=>this.sessionKey(X.snapshot.sessionName,X.snapshot.chatId)===J&&(!l1(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=lW)throw Error(`Session has reached ${lW} active Agent runs`);if([...this.runs.values()].reduce((X,V)=>X+V.snapshot.workers.filter((z)=>!a6(z.status)||V.handles.get(z.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>iW)throw Error(`global Agent worker limit ${iW} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Q+1);let H=!1;return()=>{if(H)return;H=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),LB(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)}acquireSlot($){if(this.activeTurns<cW)return this.activeTurns++,Promise.resolve();return $(),new Promise((Z)=>this.slotWaiters.push(Z))}releaseSlot(){let $=this.slotWaiters.shift();if($){$();return}this.activeTurns--}releaseWorkerSlot($,Z){if($.slotOwners.delete(Z))this.releaseSlot()}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!l1($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!a6(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,cardId:null,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRuns()}pruneRuns(){if(this.runs.size<=uW)return;let $=[...this.runs.values()].filter((Z)=>l1(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0&&Z.children.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 $){if(this.runs.size<=uW)break;if(this.runs.delete(Z.snapshot.runId),Z.snapshot.parentRunId)this.runs.get(Z.snapshot.parentRunId)?.children.delete(Z.snapshot.runId)}}}function AB($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function KB($,Z){let J=Z??$.defaultEffort;if(!$.supportedEfforts.includes(J))throw Error(`${$.displayName} does not support effort ${J}`);return J}function dW($,Z){if(Z){let J=$.workers.find((Y)=>Y.identityId===Z);if(!J)throw Error(`agent identity is not part of run ${$.runId}: ${Z}`);return J}if($.workers.length!==1)throw Error("run has multiple Agents; specify identity_id");return $.workers[0]}function l1($){return $==="completed"||$==="failed"||$==="cancelled"}function a6($){return $==="completed"||$==="failed"||$==="cancelled"}function p2($){return JSON.parse(JSON.stringify($))}function _B(){if(!VB(y0))return[];let $=[];for(let Z of zB(y0).filter((J)=>J.endsWith(".json")).sort()){let J=o6(y0,Z),Y;try{Y=JSON.parse(aW(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${j$(Q)}`)}if(!BB(Y))throw Error(`agent run artifact is invalid: ${J}`);RB(Y,J),$.push(Y)}return $}function BB($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&typeof Z.prompt==="string"&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function oW($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(j$).join("; ")}`)}function O5($){if($.some((Z)=>Z.status==="rejected"))throw oW($)}function j$($){return $ instanceof Error?$.message:String($)}function qB($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function RB($,Z){if($.promptArtifact)$.prompt=nW($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=nW(J.outputArtifact,`output for ${Z}`)}function nW($,Z){rW($);try{return aW(o6(y0,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${j$(J)}`)}}function rW($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function LB($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var cW=8,mW="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",uW=512,pW=50,lW=64,iW=128,GB;var tW=S(()=>{d0();f$();o();U$();y6();IW();R$();g$();g();GB={getCatalog:J1,startWorker:gW,sendCard:i,sendTextRaw:C,convertMessageToCard:o$,recordCardCreated:u$,replaceElementChecked:D$,patchSummaryThrottled:H0,flush:x$,cancelSummary:A$,patchSettingsChecked:K$,dispose:C$,writeArtifact:H$,writeTextArtifact:h$,loadArtifacts:_B}});function sW($){let Z=T5($,"agent run request"),J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Y=[...new Set(J.map((H)=>H.trim()).filter(Boolean))];if(Y.length===0)throw Error("agent run requires at least one identity_id");if(Y.length>64)throw Error("agent run supports at most 64 identities");let Q=ZH(Z.prompt,'agent run requires "prompt"'),W=l2(Z.effort);return{identityIds:Y,prompt:Q,...W?{effort:W}:{}}}function eW($){let Z=T5($,"agent follow-up request"),J=ZH(Z.prompt,'agent follow-up requires "prompt"'),Y=l2(Z.identity_id??Z.identityId),Q=l2(Z.effort);return{prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function $H($){let Z=T5($,"agent answer request"),J=l2(Z.identity_id??Z.identityId),Y=l2(Z.request_id??Z.requestId);if(!Y)throw Error("agent answer requires request_id");if(!Z.answers||typeof Z.answers!=="object"||Array.isArray(Z.answers))throw Error("agent answer requires an answers object");let Q={};for(let[W,H]of Object.entries(Z.answers)){if(!W.trim())throw Error("agent answer contains an empty question key");Q[W]=String(H)}if(Object.keys(Q).length===0)throw Error("agent answer requires at least one answer");return{requestId:Y,answers:Q,...J?{identityId:J}:{}}}function T5($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function ZH($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function l2($){return(typeof $==="string"?$.trim():"")||void 0}async function QH($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(A,K)=>{return Z.statusCode=A,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(K)),!0},W=jB($.headers.authorization);if(!W)return Q(401,{error:"missing bearer capability"});let H=PB(Y,W);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await O1(),Q(200,MB(J1()));if($.method==="POST"&&J.pathname==="/agents/runs")try{let A=await Y.service.startRun(H,sW(await N5($)));return Q(202,r6(A))}catch(A){return Q(409,{error:YH(A)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let V=DB(X[1]);if(!V)return Q(400,{error:"invalid agent run id encoding"});let z=X[2];try{if(!z&&$.method==="GET")return Q(200,r6(Y.service.getRun(H,V)));if(!z&&$.method==="DELETE"){let A=await Y.service.cancelRun(H,V,"cancelled by agent client");return Q(A?200:409,A?{ok:!0,run_id:V}:{error:"agent run is already terminal",run_id:V})}if(z==="follow-up"&&$.method==="POST"){let A=await Y.service.followUp(H,V,eW(await N5($)));return Q(202,r6(A))}if(z==="answer"&&$.method==="POST"){let A=await Y.service.answer(H,V,$H(await N5($)));return Q(200,r6(A))}}catch(A){return Q(409,{error:YH(A)})}return Q(405,{error:"unsupported agent endpoint"})}function PB($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function DB($){try{return decodeURIComponent($)}catch{return null}}function jB($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function N5($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>JH)throw Error(`request body exceeds ${JH} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function MB($){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 r6($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,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 YH($){return $ instanceof Error?$.message:String($)}var JH=4194304;var WH=S(()=>{y6();G$()});import{chmodSync as FB,existsSync as k5,readFileSync as VH,unlinkSync as UB}from"node:fs";import{homedir as OB}from"node:os";import{basename as EB,dirname as TB,join as S0,resolve as NB}from"node:path";function kB($={}){let Z=NB($.daemonEntry??process.argv[1]??""),J=$.runtime??process.execPath,Y=$.exists??k5,Q=TB(Z),W=S0(Q,"src","agent-cli.ts"),H=S0(Q,"lodestar-agent.js"),X=S0(Q,"dist","lodestar-agent.js"),z=/^bun(?:\.exe)?$/i.test(EB(J))?[W,H,X]:[H,X],A=z.find(Y);if(!A)throw Error(`lodestar-agent entry not found beside daemon: ${z.join(", ")}`);return{runtime:J,entry:A}}function zH($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??yB(Z,$.homeDir??OB(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??kB(),W=S0(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${XH(Q.runtime)}" "${XH(Q.entry)}" %*\r
470
+ `),allowDelegation:!1,profile:$.profile,managedSkillPluginPath:$.managedSkillPluginPath,hostEnv:{...$.hostEnv,LODESTAR_AGENT_ROLE:"worker"},serviceName:"lodestar-agent"});return PB(Y,$.prompt,$.callbacks)}function PB($,Z,J={},Y=IZ){let Q=[],W=null,H=!1,X=null,V=null,z=[],G,_,B=Date.now(),q=new Promise((U,y)=>{G=U,_=y}),L=(U)=>{if(!U)return null;try{return Y($.provider,U),J.onSession?.(U),null}catch(y){return y instanceof Error?y:Error(String(y))}},P=()=>{if($.off("assistant_text",O),$.off("tool_use",D),$.off("tool_result",E),$.off("subagent_step",x),$.off("can_use_tool",b),$.off("hook_callback",u),$.off("init",g),!$.isAlive())$.off("error",c);$.off("turn_retry",S),$.off("result",k),$.off("exit",h)},R=(U,y)=>{if(X)return X;return H=!0,z.length=0,X=Promise.resolve().then(async()=>{let w=L($.sessionId);try{await $.kill(3000)}catch(h0){V=h0 instanceof Error?h0:Error(String(h0))}P();let M0=[U,w,V].filter((h0)=>!!h0),W0=M0.length>1?AggregateError(M0,M0.map((h0)=>h0.message).join("; ")):M0[0];if(W0){_(new s2(W0,Q.join("").trim(),$.sessionId));return}let F0=$.sessionId;if(!F0){_(new s2(Error("delegated agent completed without a native session id"),Q.join("").trim(),null));return}let JZ=Q.join("").trim(),Q2=DB(y?.checkpoint,$);G({output:JZ,outputTruncated:!1,sessionId:F0,...Q2?{checkpointId:Q2}:{},durationMs:Date.now()-B,usage:$.lastUsage?{...$.lastUsage}:null})}),X},O=(U)=>{if(H||U?.parentToolUseId||typeof U?.text!=="string")return;Q.push(U.text)},j=(U)=>{if(H)return;try{J.onProgress?.(U)}catch(y){R(y instanceof Error?y:Error(String(y)))}},D=(U)=>j({at:new Date().toISOString(),phase:"started",tool:String(U?.name??"tool"),detail:""}),E=(U)=>j({at:new Date().toISOString(),phase:"completed",tool:U?.is_error?"tool error":"tool result",detail:""}),x=(U)=>j({at:new Date().toISOString(),phase:U?.phase??"info",tool:String(U?.tool??"subagent"),detail:""}),b=(U)=>{if(H)return;if(U.tool_name!=="AskUserQuestion"){try{$.sendPermissionResponse(U.request_id,"allow",{updatedInput:U.input??{}})}catch(w){R(w instanceof Error?w:Error(String(w)))}return}let y;try{y=jB(U)}catch(w){R(w instanceof Error?w:Error(String(w)));return}if(z.some((w)=>w.request.requestId===y.requestId))return;z.push({request:y,originalInput:U.input??{}});try{if(z.length===1)J.onNeedsInput?.(y)}catch(w){R(w instanceof Error?w:Error(String(w)))}},u=(U)=>{if(H)return;try{$.sendHookResponse(String(U.request_id),{})}catch(y){R(y instanceof Error?y:Error(String(y)))}},g=(U)=>{let y=L(U?.session_id??$.sessionId);if(y)R(y)},c=(U)=>{W=U instanceof Error?U:Error(String(U))},S=(U)=>{j({at:new Date().toISOString(),phase:"info",tool:"Codex 容量重试",detail:U.phase==="waiting"?`${U.message} · ${U.delayMs/1000}s 后重试 #${U.attempt}`:`正在重试 #${U.attempt}`})},k=(U)=>{let y=U?.is_error?Error(String(U.error??U.subtype??$.lastResult.subtype??"delegated agent failed")):void 0;R(y,U)},h=(U)=>{if(H)return;let y=`code=${U?.code??"null"} signal=${U?.signal??"null"}`;R(W??Error(`delegated agent exited before result (${y})`))};$.on("assistant_text",O),$.on("tool_use",D),$.on("tool_result",E),$.on("subagent_step",x),$.on("can_use_tool",b),$.on("hook_callback",u),$.on("init",g),$.on("error",c),$.on("turn_retry",S),$.on("result",k),$.on("exit",h);try{$.sendInitialize(),$.sendUserText(Z)}catch(U){R(U instanceof Error?U:Error(String(U)))}return{done:q,isAlive:()=>$.isAlive(),pendingInput:()=>z[0]?.request??null,answer(U,y){let w=z[0];if(!w)throw Error("delegated agent is not waiting for input");if(w.request.requestId!==U)throw Error(`delegated agent input request mismatch: expected ${w.request.requestId}`);if($.sendPermissionResponse(U,"allow",{updatedInput:{...w.originalInput,answers:y}}),z.shift(),z[0])J.onNeedsInput?.(z[0].request)},async cancel(U="delegated agent cancelled"){let y=H;if(await R(Error(U)),await q.catch(()=>{}),y){if($.isAlive())await $.kill(3000);V=null,P()}if(V)throw V}}}function jB($){let Z=$.input??{},Y=(Array.isArray(Z.questions)?Z.questions:[Z]).map((Q,W)=>RB(Q,W));if(Y.length===0)throw Error("delegated agent input request contains no questions");return{requestId:String($.request_id),...$.tool_use_id?{toolUseId:$.tool_use_id}:{},questions:Y}}function RB($,Z){let J=$&&typeof $==="object"?$:{question:$},Y=String(J.question??J.prompt??J.title??"").trim();if(!Y)throw Error(`delegated agent input question ${Z+1} is empty`);let Q=String(J.id??Y),W=Array.isArray(J.options)?J.options.map((H)=>{if(typeof H==="string")return{label:H};let X=H&&typeof H==="object"?H:{};return{label:String(X.label??X.value??""),...X.description?{description:String(X.description)}:{}}}).filter((H)=>H.label):[];return{id:Q,...J.header?{header:String(J.header)}:{},question:Y,options:W}}function DB($,Z){if(typeof $?.id==="string"&&$.id)return $.id;if(Z.provider==="codex"&&typeof Z.lastCompletedTurnId==="string"&&Z.lastCompletedTurnId)return Z.lastCompletedTurnId;if(Z.provider==="claude"&&Z.lastAssistantUuid)return Z.lastAssistantUuid;return}var s2;var $H=N(()=>{R7();j4();G0();g5();s2=class s2 extends Error{output;sessionId;constructor($,Z,J){super($.message,{cause:$});this.output=Z;this.sessionId=J;this.name="AgentWorkerFailure"}}});import{createHash as MB,randomBytes as FB,randomUUID as UB}from"node:crypto";import{existsSync as OB,readdirSync as EB,readFileSync as zH}from"node:fs";import{join as V6}from"node:path";class c5{deps;runs=new Map;capabilities=new Map;activeTurns=0;slotWaiters=[];cancellationEpochBySession=new Map;startingWorkers=0;startingRunsBySession=new Map;constructor($=TB){this.deps=$;this.loadDurableRuns()}rootPrincipal($){return{kind:"session",session:$,depth:-1}}principalForCapability($){return this.capabilities.get($)??null}async startRun($,Z){if($.kind!=="session")throw Error(JH);let J=this.reserveCapacity($,Z.identityIds.length);try{return await this.createRun($.session,Z,{cancellationEpoch:this.currentCancellationEpoch($.session)})}finally{J()}}async followUp($,Z,J){if($.kind!=="session")throw Error(JH);let Y=this.requireMutableDescendant($,Z);if(!s1(Y.snapshot.status))throw Error("agent follow-up requires a terminal source run");let Q=XH(Y.snapshot,J.identityId);if(Y.handles.get(Q.identityId)?.isAlive?.())throw Error("Agent process has not stopped; cannot start follow-up yet");if(!Q.sessionId)throw Error(`${Q.identityName} has no resumable native session id`);let W=J.effort??Q.effort,H=this.reserveCapacity($,1);try{return await this.createRun($.session,{identityIds:[Q.identityId],prompt:J.prompt,effort:W},{parentRunId:Y.snapshot.runId,parentKind:"follow_up",cancellationEpoch:this.currentCancellationEpoch($.session),resumeByIdentity:new Map([[Q.identityId,Q.sessionId]])})}finally{H()}}async answer($,Z,J){let Y=this.requireMutableDescendant($,Z),Q=XH(Y.snapshot,J.identityId);if(Q.status!=="needs_input"||!Q.pendingInput)throw Error(`${Q.identityName} is not waiting for input`);if(Q.pendingInput.requestId!==J.requestId)throw Error(`input request mismatch: expected ${Q.pendingInput.requestId}`);let W=Y.handles.get(Q.identityId);if(!W)throw Error("waiting agent process is no longer alive; start a follow-up run");W.answer(J.requestId,J.answers);let H=W.pendingInput();if(Q.status=H?"needs_input":"running",H)Q.pendingInput=H;else delete Q.pendingInput;return delete Q.queuedReason,this.refreshNonterminalStatus(Y),this.persist(Y),await this.updateWorkerCard(Y,Q),e2(Y.snapshot)}getRun($,Z){return e2(this.requireAccessibleRun($,Z).snapshot)}async cancelRun($,Z,J="agent run cancelled"){let Y=this.requireMutableDescendant($,Z);if(!this.treeHasActiveRun(Y))return!1;return await this.cancelTree(Y,J),!0}async cancelSessionRuns($,Z,J){this.bumpCancellationEpoch($,Z);let Y=[...this.runs.values()].filter((W)=>W.snapshot.sessionName===$&&W.snapshot.chatId===Z&&!W.snapshot.parentRunId&&this.treeHasActiveRun(W)),Q=await Promise.allSettled(Y.map((W)=>this.cancelTree(W,J)));I5(Q)}async shutdown($){let Z=new Set([...this.runs.values()].map((H)=>`${H.snapshot.sessionName}\x00${H.snapshot.chatId}`));for(let H of Z){let[X,V]=H.split("\x00");this.bumpCancellationEpoch(X,V)}let J=[...this.runs.values()].filter((H)=>!H.snapshot.parentRunId&&this.treeHasActiveRun(H)),Y=await Promise.allSettled(J.map((H)=>this.cancelTree(H,$))),Q=[...this.runs.values()].flatMap((H)=>[...H.handles.values()]),W=Y.some((H)=>H.status==="rejected")?[]:await Promise.allSettled(Q.map((H)=>H.cancel($)));I5([...Y,...W])}async createRun($,Z,J){this.pruneRuns();let Y;if(J.parentRunId){if(Y=this.runs.get(J.parentRunId),!Y)throw Error(`parent agent run not found: ${J.parentRunId}`);this.assertSameSession(Y,$)}let Q=this.deps.getCatalog(),W=Z.identityIds.map((q)=>{let L=Q.identities.find((P)=>P.id===q);if(!L)throw Error(`agent identity not found: ${q}`);if(L.status!=="ready")throw Error(`${L.displayName}: ${L.reason??L.status}`);return L}),H=W.map((q)=>NB(q,kB(q,Z.effort),J.resumeByIdentity?.get(q.id))),X=`agent_${UB()}`,V={runId:X,sessionName:$.sessionName,chatId:$.chatId,workDir:$.workDir,prompt:Z.prompt,...J.parentRunId?{parentRunId:J.parentRunId}:{},...J.parentKind?{parentKind:J.parentKind}:{},depth:0,status:"queued",workers:H,createdAt:new Date().toISOString()},z=await this.deps.sendCard($.chatId,u8(V));if(!z)throw Error("agent card creation failed; delegated agents were not started");let G;try{G=await this.deps.convertMessageToCard(z)}catch(q){throw await this.deps.sendTextRaw($.chatId,`❌ agent 卡片初始化失败,Agent 未启动: ${D0(q)}`),q}V.cardMessageId=z,this.deps.recordCardCreated(G,H.length+2,(q)=>{A(`agent: card write failed run=${X} code=${q??"MISS"}`)});let _={snapshot:V,session:$,cardId:G,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:!1,finalizing:!1,finalized:!1,persistedArtifacts:new Set};if(this.runs.set(X,_),J.parentRunId)Y?.children.add(X);if(this.currentCancellationEpoch($)!==J.cancellationEpoch){_.cancelled=!0;let q="任务已在启动前取消";for(let L of _.snapshot.workers)L.status="cancelled",L.error=q,L.finishedAt=new Date().toISOString();return this.persist(_),await Promise.all(_.snapshot.workers.map((L)=>this.updateWorkerCard(_,L))),await this.finalizeRun(_,"cancelled",q),e2(_.snapshot)}this.persist(_);for(let q of W){let L=J.resumeByIdentity?.get(q.id);this.executeWorker(_,q,Z.prompt,L).catch((P)=>{A(`agent: run=${X} worker=${q.id} crashed: ${D0(P)}`)})}return e2(V)}async executeWorker($,Z,J,Y){let Q=$.snapshot.workers.find((H)=>H.identityId===Z.id);if(await this.acquireSlot(()=>{Q.queuedReason=`等待执行名额(最多同时运行 ${ZH} 个 Agent)`,this.persist($),this.updateWorkerCard($,Q)}),$.slotOwners.add(Z.id),$.cancelled){this.releaseWorkerSlot($,Z.id);return}let W="";try{if(W=FB(32).toString("base64url"),this.capabilities.set(W,{kind:"worker",session:$.session,runId:$.snapshot.runId,identityId:Z.id,depth:$.snapshot.depth}),$.capabilityByIdentity.set(Z.id,W),Q.status="running",Q.startedAt=new Date().toISOString(),delete Q.queuedReason,this.refreshNonterminalStatus($),this.persist($),await this.updateWorkerCard($,Q),$.cancelled)return;let H=this.deps.startWorker({identity:Z,effort:Q.effort,workDir:$.snapshot.workDir,prompt:J,resumeSessionId:Y,developerInstructions:$.session.delegatedAgentDeveloperInstructions(Z.provider),profile:xB(y1($.session.worktreeProjectName())),...process.env.LODESTAR_DISABLE_SKILL_SYNC==="1"?{}:{managedSkillPluginPath:w$},hostEnv:{LODESTAR_AGENT_URL:f4(v.notify.bind,v.notify.port),LODESTAR_AGENT_CAPABILITY:W,LODESTAR_AGENT_SESSION:$.snapshot.sessionName},callbacks:{onNeedsInput:(V)=>{if($.cancelled)return;Q.status="needs_input",Q.pendingInput=V,this.refreshNonterminalStatus($),this.persist($),this.updateWorkerCard($,Q)},onProgress:(V)=>this.recordStep($,Q,V),onSession:(V)=>{if(Q.sessionId===V)return;Q.sessionId=V,this.persist($)}}});$.handles.set(Z.id,H);let X=await H.done;if($.cancelled)return;this.clearProgressTimer($,Z.id),Q.status="completed",Q.output=X.output,Q.outputTruncated=X.outputTruncated,Q.sessionId=X.sessionId,Q.checkpointId=X.checkpointId,Q.durationMs=X.durationMs,Q.usage=X.usage,Q.finishedAt=new Date().toISOString(),delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}catch(H){if(H instanceof s2){if(Q.output=H.output,Q.outputTruncated=!1,H.sessionId)Q.sessionId=H.sessionId;this.persist($)}if(!$.cancelled){if(this.clearProgressTimer($,Z.id),Q.status="failed",Q.error=D0(H),Q.finishedAt=new Date().toISOString(),Q.startedAt)Q.durationMs=Date.now()-Date.parse(Q.startedAt);delete Q.pendingInput,this.persist($),await this.updateWorkerCard($,Q)}}finally{if(!$.handles.get(Z.id)?.isAlive?.())$.handles.delete(Z.id),this.releaseWorkerSlot($,Z.id);if(W)this.capabilities.delete(W);$.capabilityByIdentity.delete(Z.id),this.recomputeRun($)}}recordStep($,Z,J){if($.cancelled||$.finalizing||$.finalized||X6(Z.status))return;if(Z.steps.push(J),Z.steps.length>QH)Z.steps.splice(0,Z.steps.length-QH);if($.progressTimers.has(Z.identityId))return;let Y=setTimeout(()=>{$.progressTimers.delete(Z.identityId),this.updateWorkerCard($,Z)},250);$.progressTimers.set(Z.identityId,Y)}clearProgressTimer($,Z){let J=$.progressTimers.get(Z);if(J)clearTimeout(J);$.progressTimers.delete(Z)}refreshNonterminalStatus($){if($.cancelled)return;if($.snapshot.workers.some((Z)=>Z.status==="needs_input"))$.snapshot.status="needs_input";else if($.snapshot.workers.some((Z)=>Z.status==="running"))$.snapshot.status="running";else $.snapshot.status="queued";delete $.snapshot.finishedAt}recomputeRun($){if($.cancelled||$.finalized||$.finalizing)return;let Z=$.snapshot.workers;if(Z.some((Y)=>Y.status==="needs_input"||Y.status==="running"||Y.status==="queued")){this.refreshNonterminalStatus($),this.persist($);return}let J=Z.some((Y)=>Y.status==="failed")?"failed":"completed";this.finalizeRun($,J,J==="failed"?"一个或多个 Agent 失败":void 0).catch((Y)=>{$.finalizing=!1,$.finalized=!1,$.snapshot.status="failed",$.snapshot.error=`Agent terminal persistence failed: ${D0(Y)}`,A(`agent: terminal finalization failed run=${$.snapshot.runId}: ${D0(Y)}`),this.deps.sendTextRaw($.snapshot.chatId,`❌ agent ${$.snapshot.runId} 收尾失败: ${D0(Y)}`).catch((Q)=>A(`agent: terminal failure delivery failed: ${D0(Q)}`))})}async cancelTree($,Z){let J=!s1($.snapshot.status)&&!$.cancelled||$.handles.size>0,Y=[];if(J){$.cancelled=!0;for(let W of[...$.progressTimers.keys()])this.clearProgressTimer($,W);for(let W of $.capabilityByIdentity.values())this.capabilities.delete(W);$.capabilityByIdentity.clear()}while(!0){let W=[...$.children].map((X)=>this.runs.get(X)).filter((X)=>!!X&&this.treeHasActiveRun(X));if(W.length===0)break;let H=await Promise.allSettled(W.map((X)=>this.cancelTree(X,Z)));if(Y.push(...H),H.some((X)=>X.status==="rejected"))break}if(!J){I5(Y);return}if(Y.push(...await Promise.allSettled([...$.handles].map(async([W,H])=>{if(await H.cancel(Z),H.isAlive?.())throw Error(`${W}: Agent process is still alive after cancellation`);$.handles.delete(W),this.releaseWorkerSlot($,W)}))),Y.some((W)=>W.status==="rejected")){let W=GH(Y);throw $.snapshot.status="failed",$.snapshot.error=W.message,this.persist($),await this.deps.sendTextRaw($.snapshot.chatId,`❌ Agent 取消未完成: ${W.message}`).catch((H)=>A(`agent: cancellation failure notice failed: ${D0(H)}`)),W}let Q=[];for(let W of $.snapshot.workers)if(!X6(W.status))W.status="cancelled",W.error=Z,W.finishedAt=new Date().toISOString(),delete W.pendingInput,Q.push(W);await Promise.all(Q.map((W)=>this.updateWorkerCard($,W))),await this.finalizeRun($,"cancelled",Z)}async finalizeRun($,Z,J){if($.finalized||$.finalizing)return;$.finalizing=!0;for(let Y of[...$.progressTimers.keys()])this.clearProgressTimer($,Y);if($.snapshot.status=Z,$.snapshot.finishedAt=new Date().toISOString(),J)$.snapshot.error=J;try{if($.cardId){if(this.deps.cancelSummary($.cardId),await this.deps.flush($.cardId),!await this.deps.replaceElementChecked($.cardId,M.agentRunFooter,m2($.snapshot)))this.recordPresentationError($,"agent footer update MISS");if(!await this.deps.patchSettingsChecked($.cardId,{config:{streaming_mode:!1,summary:{content:u2($.snapshot)}}}))this.recordPresentationError($,"agent terminal settings update MISS");await this.deps.flush($.cardId),await this.deps.dispose($.cardId)}}catch(Y){this.recordPresentationError($,`agent card finalization failed: ${D0(Y)}`)}if($.finalizing=!1,this.persist($),$.finalized=!0,$.snapshot.presentationErrors?.length)await this.deps.sendTextRaw($.snapshot.chatId,`⚠️ agent ${$.snapshot.runId} 结果已保存,但卡片有 ${$.snapshot.presentationErrors.length} 个呈现错误。`).catch((Y)=>A(`agent: warning delivery failed run=${$.snapshot.runId}: ${D0(Y)}`))}async updateWorkerCard($,Z){if(!$.cardId||$.finalized)return;try{if(!await this.deps.replaceElementChecked($.cardId,O9(Z.identityId),U9(Z,E9($.snapshot.workers.length),$.snapshot.workers.length===1)))this.recordPresentationError($,`agent worker card MISS: ${Z.identityName}`);if(!await this.deps.replaceElementChecked($.cardId,M.agentRunFooter,m2($.snapshot)))A(`agent: progress update MISS run=${$.snapshot.runId}; later updates will refresh it`);this.deps.patchSummaryThrottled($.cardId,u2($.snapshot))}catch(J){this.recordPresentationError($,`agent worker card update failed (${Z.identityName}): ${D0(J)}`)}}recordPresentationError($,Z){let J=$.snapshot.presentationErrors??[];if(!J.includes(Z))J.push(Z);$.snapshot.presentationErrors=J,A(`agent: ${Z} run=${$.snapshot.runId}`)}persist($){if(!$.snapshot.promptArtifact)$.snapshot.promptArtifact=`${$.snapshot.runId}.prompt.txt`;this.persistTextArtifact($,$.snapshot.promptArtifact,$.snapshot.prompt);for(let J of $.snapshot.workers){if(!J.output)continue;if(!J.outputArtifact){let Y=MB("sha256").update(J.identityId).digest("hex").slice(0,16);J.outputArtifact=`${$.snapshot.runId}.${Y}.output.txt`}this.persistTextArtifact($,J.outputArtifact,J.output)}let Z=e2($.snapshot);Z.prompt="";for(let J of Z.workers)J.output="";this.deps.writeArtifact(V6(C$,`${$.snapshot.runId}.json`),Z)}persistTextArtifact($,Z,J){if($.persistedArtifacts.has(Z))return;AH(Z),this.deps.writeTextArtifact(V6(C$,Z),J),$.persistedArtifacts.add(Z)}requireAccessibleRun($,Z){let J=this.runs.get(Z);if(!J||!this.canAccess($,J))throw Error(`agent run not found: ${Z}`);if(this.assertSameSession(J,$.session),!J.session)J.session=$.session;return J}requireMutableDescendant($,Z){let J=this.requireAccessibleRun($,Z);if($.kind==="worker"&&J.snapshot.runId===$.runId)throw Error("worker capability cannot mutate its containing run");return J}canAccess($,Z){if(Z.snapshot.sessionName!==$.session.sessionName||Z.snapshot.chatId!==$.session.chatId)return!1;if($.kind==="session")return!0;let J=Z;while(J){if(J.snapshot.runId===$.runId)return!0;J=J.snapshot.parentRunId?this.runs.get(J.snapshot.parentRunId):void 0}return!1}assertSameSession($,Z){if($.snapshot.sessionName!==Z.sessionName||$.snapshot.chatId!==Z.chatId||$.snapshot.workDir!==Z.workDir)throw Error("agent run belongs to a different Session")}treeHasActiveRun($){if($.handles.size>0)return!0;if(!s1($.snapshot.status))return!0;for(let Z of $.children){let J=this.runs.get(Z);if(J&&this.treeHasActiveRun(J))return!0}return!1}reserveCapacity($,Z){let J=this.sessionKey($.session.sessionName,$.session.chatId),Y=[...this.runs.values()].filter((X)=>this.sessionKey(X.snapshot.sessionName,X.snapshot.chatId)===J&&(!s1(X.snapshot.status)||X.handles.size>0)).length,Q=this.startingRunsBySession.get(J)??0;if(Y+Q>=WH)throw Error(`Session has reached ${WH} active Agent runs`);if([...this.runs.values()].reduce((X,V)=>X+V.snapshot.workers.filter((z)=>!X6(z.status)||V.handles.get(z.identityId)?.isAlive?.()).length,0)+this.startingWorkers+Z>HH)throw Error(`global Agent worker limit ${HH} would be exceeded`);this.startingWorkers+=Z,this.startingRunsBySession.set(J,Q+1);let H=!1;return()=>{if(H)return;H=!0,this.startingWorkers=Math.max(0,this.startingWorkers-Z),CB(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)}acquireSlot($){if(this.activeTurns<ZH)return this.activeTurns++,Promise.resolve();return $(),new Promise((Z)=>this.slotWaiters.push(Z))}releaseSlot(){let $=this.slotWaiters.shift();if($){$();return}this.activeTurns--}releaseWorkerSlot($,Z){if($.slotOwners.delete(Z))this.releaseSlot()}loadDurableRuns(){for(let $ of this.deps.loadArtifacts()){if(!s1($.status)){$.status="failed",$.error="daemon restarted before this Agent run reached a terminal state",$.finishedAt=new Date().toISOString();for(let J of $.workers)if(!X6(J.status))J.status="failed",J.error=$.error,J.finishedAt=$.finishedAt,delete J.pendingInput}let Z={snapshot:$,session:null,cardId:null,handles:new Map,slotOwners:new Set,capabilityByIdentity:new Map,progressTimers:new Map,children:new Set,cancelled:$.status==="cancelled",finalizing:!1,finalized:!0,persistedArtifacts:new Set([...$.promptArtifact?[$.promptArtifact]:[],...$.workers.flatMap((J)=>J.outputArtifact?[J.outputArtifact]:[])])};this.runs.set($.runId,Z),this.persist(Z)}for(let $ of this.runs.values())if($.snapshot.parentRunId)this.runs.get($.snapshot.parentRunId)?.children.add($.snapshot.runId);this.pruneRuns()}pruneRuns(){if(this.runs.size<=YH)return;let $=[...this.runs.values()].filter((Z)=>s1(Z.snapshot.status)&&Z.handles.size===0&&Z.slotOwners.size===0&&Z.children.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 $){if(this.runs.size<=YH)break;if(this.runs.delete(Z.snapshot.runId),Z.snapshot.parentRunId)this.runs.get(Z.snapshot.parentRunId)?.children.delete(Z.snapshot.runId)}}}function NB($,Z,J){return{identityId:$.id,identityName:$.displayName,tokenSourceId:$.tokenSourceId,provider:$.provider,model:$.model,effort:Z,status:"queued",output:"",...J?{sessionId:J}:{},steps:[]}}function kB($,Z){let J=Z??$.defaultEffort;if(!$.supportedEfforts.includes(J))throw Error(`${$.displayName} does not support effort ${J}`);return J}function XH($,Z){if(Z){let J=$.workers.find((Y)=>Y.identityId===Z);if(!J)throw Error(`agent identity is not part of run ${$.runId}: ${Z}`);return J}if($.workers.length!==1)throw Error("run has multiple Agents; specify identity_id");return $.workers[0]}function s1($){return $==="completed"||$==="failed"||$==="cancelled"}function X6($){return $==="completed"||$==="failed"||$==="cancelled"}function e2($){return JSON.parse(JSON.stringify($))}function SB(){if(!OB(C$))return[];let $=[];for(let Z of EB(C$).filter((J)=>J.endsWith(".json")).sort()){let J=V6(C$,Z),Y;try{Y=JSON.parse(zH(J,"utf8"))}catch(Q){throw Error(`agent run artifact is unreadable (${J}): ${D0(Q)}`)}if(!yB(Y))throw Error(`agent run artifact is invalid: ${J}`);bB(Y,J),$.push(Y)}return $}function yB($){if(!$||typeof $!=="object")return!1;let Z=$;return typeof Z.runId==="string"&&Z.runId.startsWith("agent_")&&typeof Z.sessionName==="string"&&typeof Z.chatId==="string"&&typeof Z.workDir==="string"&&typeof Z.prompt==="string"&&typeof Z.depth==="number"&&typeof Z.status==="string"&&Array.isArray(Z.workers)&&typeof Z.createdAt==="string"}function GH($){let Z=$.flatMap((J)=>J.status==="rejected"?[J.reason]:[]);return AggregateError(Z,`Agent cancellation failed: ${Z.map(D0).join("; ")}`)}function I5($){if($.some((Z)=>Z.status==="rejected"))throw GH($)}function D0($){return $ instanceof Error?$.message:String($)}function xB($){return $?{...$,tools:void 0,strictMcp:!1,loadProjectMcp:!0}:{strictMcp:!1,loadProjectMcp:!0}}function bB($,Z){if($.promptArtifact)$.prompt=VH($.promptArtifact,`prompt for ${Z}`);for(let J of $.workers)if(J.outputArtifact)J.output=VH(J.outputArtifact,`output for ${Z}`)}function VH($,Z){AH($);try{return zH(V6(C$,$),"utf8")}catch(J){throw Error(`${Z} is unreadable (${$}): ${D0(J)}`)}}function AH($){if(!/^[A-Za-z0-9._-]+$/.test($))throw Error(`invalid Agent artifact name: ${$}`)}function CB($,Z){let J=($.get(Z)??0)-1;if(J>0)$.set(Z,J);else $.delete(Z)}var ZH=8,JH="Delegated Agents cannot delegate again; ask the main Agent to assign additional work.",YH=512,QH=50,WH=64,HH=128,TB;var _H=N(()=>{o$();f0();s();U0();i9();$H();L0();I0();I();TB={getCatalog:W1,startWorker:eW,sendCard:i,sendTextRaw:C,convertMessageToCard:t0,recordCardCreated:p0,replaceElementChecked:R0,patchSummaryThrottled:H$,flush:b0,cancelSummary:A0,patchSettingsChecked:_0,dispose:C0,writeArtifact:H0,writeTextArtifact:g0,loadArtifacts:SB}});function KH($){let Z=m5($,"agent run request"),J=Array.isArray(Z.identity_ids)?Z.identity_ids.map(String):Array.isArray(Z.identityIds)?Z.identityIds.map(String):[],Y=[...new Set(J.map((H)=>H.trim()).filter(Boolean))];if(Y.length===0)throw Error("agent run requires at least one identity_id");if(Y.length>64)throw Error("agent run supports at most 64 identities");let Q=LH(Z.prompt,'agent run requires "prompt"'),W=$4(Z.effort);return{identityIds:Y,prompt:Q,...W?{effort:W}:{}}}function BH($){let Z=m5($,"agent follow-up request"),J=LH(Z.prompt,'agent follow-up requires "prompt"'),Y=$4(Z.identity_id??Z.identityId),Q=$4(Z.effort);return{prompt:J,...Y?{identityId:Y}:{},...Q?{effort:Q}:{}}}function qH($){let Z=m5($,"agent answer request"),J=$4(Z.identity_id??Z.identityId),Y=$4(Z.request_id??Z.requestId);if(!Y)throw Error("agent answer requires request_id");if(!Z.answers||typeof Z.answers!=="object"||Array.isArray(Z.answers))throw Error("agent answer requires an answers object");let Q={};for(let[W,H]of Object.entries(Z.answers)){if(!W.trim())throw Error("agent answer contains an empty question key");Q[W]=String(H)}if(Object.keys(Q).length===0)throw Error("agent answer requires at least one answer");return{requestId:Y,answers:Q,...J?{identityId:J}:{}}}function m5($,Z){if(!$||typeof $!=="object"||Array.isArray($))throw Error(`${Z} must be an object`);return $}function LH($,Z){let J=String($??"");if(!J.trim())throw Error(Z);if(J.length>800000)throw Error("agent prompt exceeds 800000 chars");return J}function $4($){return(typeof $==="string"?$.trim():"")||void 0}async function RH($,Z,J,Y){if(J.pathname!=="/agents"&&!J.pathname.startsWith("/agents/"))return!1;let Q=(G,_)=>{return Z.statusCode=G,Z.setHeader("content-type","application/json"),Z.end(JSON.stringify(_)),!0},W=vB($.headers.authorization);if(!W)return Q(401,{error:"missing bearer capability"});let H=wB(Y,W);if(!H)return Q(403,{error:"invalid or stale agent capability"});if($.method==="GET"&&J.pathname==="/agents/identities")return await k1(),Q(200,hB(W1()));if($.method==="POST"&&J.pathname==="/agents/runs")try{let G=await Y.service.startRun(H,KH(await u5($)));return Q(202,z6(G))}catch(G){return Q(409,{error:jH(G)})}let X=J.pathname.match(/^\/agents\/runs\/([^/]+)(?:\/(follow-up|answer))?$/);if(!X)return Q(405,{error:"unsupported agent endpoint"});let V=fB(X[1]);if(!V)return Q(400,{error:"invalid agent run id encoding"});let z=X[2];try{if(!z&&$.method==="GET")return Q(200,z6(Y.service.getRun(H,V)));if(!z&&$.method==="DELETE"){let G=await Y.service.cancelRun(H,V,"cancelled by agent client");return Q(G?200:409,G?{ok:!0,run_id:V}:{error:"agent run is already terminal",run_id:V})}if(z==="follow-up"&&$.method==="POST"){let G=await Y.service.followUp(H,V,BH(await u5($)));return Q(202,z6(G))}if(z==="answer"&&$.method==="POST"){let G=await Y.service.answer(H,V,qH(await u5($)));return Q(200,z6(G))}}catch(G){return Q(409,{error:jH(G)})}return Q(405,{error:"unsupported agent endpoint"})}function wB($,Z){let J=$.authorizeSession(Z);if(J)return $.service.rootPrincipal(J);return $.service.principalForCapability(Z)}function fB($){try{return decodeURIComponent($)}catch{return null}}function vB($){return $?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim()??""}async function u5($){let Z="";for await(let J of $)if(Z+=J.toString(),Buffer.byteLength(Z)>PH)throw Error(`request body exceeds ${PH} bytes`);try{return JSON.parse(Z||"{}")}catch{throw Error("bad json")}}function hB($){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 z6($){return{run_id:$.runId,session_name:$.sessionName,prompt:$.prompt,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 jH($){return $ instanceof Error?$.message:String($)}var PH=4194304;var DH=N(()=>{i9();G0()});import{chmodSync as gB,existsSync as p5,readFileSync as UH,unlinkSync as IB}from"node:fs";import{homedir as cB}from"node:os";import{basename as mB,dirname as uB,join as b$,resolve as pB}from"node:path";function lB($={}){let Z=pB($.daemonEntry??process.argv[1]??""),J=$.runtime??process.execPath,Y=$.exists??p5,Q=uB(Z),W=b$(Q,"src","agent-cli.ts"),H=b$(Q,"lodestar-agent.js"),X=b$(Q,"dist","lodestar-agent.js"),z=/^bun(?:\.exe)?$/i.test(mB(J))?[W,H,X]:[H,X],G=z.find(Y);if(!G)throw Error(`lodestar-agent entry not found beside daemon: ${z.join(", ")}`);return{runtime:J,entry:G}}function OH($={}){let Z=$.platform??process.platform,J=$.env??process.env,Y=$.targetDir??dB(Z,$.homeDir??cB(),$.localAppData??process.env.LOCALAPPDATA),Q=$.launch??lB(),W=b$(Y,Z==="win32"?"lodestar-agent.cmd":"lodestar-agent"),H=Z==="win32"?`@"${FH(Q.runtime)}" "${FH(Q.entry)}" %*\r
380
471
  `:`#!/bin/sh
381
- exec ${HH(Q.runtime)} ${HH(Q.entry)} "$@"
382
- `,X=k5(W)?VH(W,"utf8"):null;if(X!==H)s5(W,H),G(`command: ${X===null?"installed":"updated"} ${W}`);else FB(W,448);return xB(J,Y,Z),SB(Y,Z),W}function SB($,Z){let J=S0($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!k5(J))return;try{let Y=VH(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){G(`command: obsolete path preserved because ownership is unclear ${J}`);return}UB(J),G(`command: removed obsolete ${J}`)}catch(Y){G(`command: obsolete removal failed (${J}): ${Y}`)}}function yB($,Z,J){if($==="win32")return S0(J??S0(Z,"AppData","Local"),"Lodestar","bin");return S0(Z,".local","bin")}function xB($,Z,J){let Y=J==="win32"?Object.keys($).find((X)=>X.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",W=$[Y]??"",H=(X)=>J==="win32"?X.toLowerCase():X;if(W.split(Q).some((X)=>H(X)===H(Z)))return;$[Y]=W?`${Z}${Q}${W}`:Z}function HH($){return`'${$.replaceAll("'",`'"'"'`)}'`}function XH($){return $.replaceAll('"','""')}var GH=S(()=>{g();g$()});function AH($,Z,J){return $>0&&Z-$>J}function KH($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function S5($){return typeof $==="string"&&$.length>0?$:void 0}function _H($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=S5(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=S5(J.file_key);if(!Y)return null;let Q=S5(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function BH($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function qH($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}function bB($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!CB.has(J))return`不支持的操作: ${J}`;if(J!=="notify_callback"&&!String($?.context?.open_chat_id??""))return"回调缺少 chat_id,操作未执行";if(J!=="notify_callback"&&!String($?.context?.open_message_id??""))return"回调缺少原卡 message_id,操作未执行";if(J==="permission"&&!["allow","allow_always","deny"].includes(String(Z.decision??"")))return"无效的权限决定,操作未执行";return null}class x5{tails=new Map;accepting=!0;tryEnqueue($,Z){if(!this.accepting)return{accepted:!1,reason:"closed"};let J=$.trim();if(!J)return{accepted:!1,reason:"invalid-key"};let Q=(this.tails.get(J)??Promise.resolve()).then(Z),W;return W=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===W)this.tails.delete(J)}),this.tails.set(J,W),{accepted:!0,completion:Q}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function RH($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class C5{completedTtlMs;now;maxCompletedEntries;inflight=new Set;completed=new Map;constructor($=30000,Z=Date.now,J=4096){this.completedTtlMs=$;this.now=Z;this.maxCompletedEntries=J}claim($){return this.claimAll([$])}claimAll($){if(this.prune(),$.some((Z)=>this.inflight.has(Z)))return"inflight";if($.some((Z)=>this.completed.has(Z)))return"completed";for(let Z of $)this.inflight.add(Z);return"started"}complete($){this.completeAll([$])}completeAll($){this.prune();let Z=this.now()+this.completedTtlMs;for(let J of $)this.inflight.delete(J),this.completed.delete(J),this.completed.set(J,Z);while(this.completed.size>this.maxCompletedEntries){let J=this.completed.keys().next().value;if(J===void 0)break;this.completed.delete(J)}}fail($){this.failAll([$])}failAll($){for(let Z of $)this.inflight.delete(Z)}prune(){let $=this.now();for(let[Z,J]of this.completed)if(J<=$)this.completed.delete(Z)}}function y5($){if(Array.isArray($))return`[${$.map(y5).join(",")}]`;if($===void 0)return"undefined";if(!$||typeof $!=="object")return JSON.stringify($);return`{${Object.entries($).sort(([Z],[J])=>Z.localeCompare(J)).map(([Z,J])=>`${JSON.stringify(Z)}:${y5(J)}`).join(",")}}`}function fB($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),W=null;switch(J){case"menu":W={request_id:Z.request_id};break;case"permission":W={request_id:Z.request_id};break;case"ask":W={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":W={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":W={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":W={guid:Z.guid};break;case"tasklist_enable":W={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":W={source_id:Z.source_id};break;case"agent_identity_page":W={panel_id:Z.panel_id,page:Z.page};break;case"notify_callback":W={notify_id:Z.notify_id};break;case"provider_select":case"model_select":case"model_custom_prompt":case"model_panel_cancel":case"model_effort_select":W={panel_id:Z.panel_id};break;default:W=Z}return`${Y}\x00${Q}\x00${J}\x00${y5(W)}`}function wB($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${fB($)}`,...$?.action?.value?.kind==="agent_identity_page"?{repeatable:!0}:{}}}function vB(){return new Promise(($)=>setTimeout($,0))}function i2($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function LH($){let Z=$.afterAck??vB,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(W){J(W)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let W=bB(Q);if(W)return $.responses.invalid(Q,W);let H=wB(Q),X=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],V=$.deduper.claimAll(X);if(V==="inflight")return $.responses.inflight(Q);if(V==="completed")return $.responses.completed(Q);let z=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(B){$.deduper.failAll(X),J(B);return}let A;try{A=await $.execute(Q)}catch(B){i2($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,B));return}await Y(async()=>{try{await $.present(Q,A)}catch(B){await $.presentPresentationFailure(Q,B)}});let K;try{K=$.completion(Q,A)}catch(B){i2($.deduper,H,!1),J(B);return}if(K){let B=K.then((q)=>{i2($.deduper,H,q==="complete")},(q)=>{i2($.deduper,H,!1),J(q)});$.track(B);return}i2($.deduper,H,$.businessSucceeded(Q,A))});if(!z.accepted)return $.deduper.failAll(X),$.responses.closed(Q);return $.track(z.completion),z.completion.catch(J),$.responses.accepted(Q)}}}var CB;var PH=S(()=>{CB=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","notify_callback"])});function K0($){return $ instanceof Error?$.message:String($)}function DH($,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 jH($){let Z=(Q,W)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==W)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${W}"`);if(!H)H=$.createSession(W,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let W;try{if(z$(Q.launch,Q.routing.provider,Q.workDir),Q.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(W=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!W.created)return{ok:!1,chatId:W.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(X){let V=K0(X);return $.log(`temp-session: create "${Q.chatName}" failed: ${V}`),{ok:!1,error:V}}let H=async()=>{let X=null;try{if($.registerTempSessionLease(Q.chatName,W.chatId),X=Z(W.chatId,Q.chatName),X.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(X.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${X.workDir}`);if(X.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await X.startForked(Q.launch,{announce:!1}):await X.start({announce:!1})))throw Error(`${X.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:W.chatId}}catch(V){let z=K0(V);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${z}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(K){let B=K0(K);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};无法确认 Session 已停止,临时群/session 仍保留: ${B}`}}if(!W.created)return{ok:!1,error:`${z};既有群保留,未执行删除`};let A;try{let K=await $.disbandChatForSessionExact(Q.chatName,W.chatId);A=DH(Q.chatName,W.chatId,K)}catch(K){let B=K0(K);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};自动解散失败,临时群/session 仍保留: ${B}`}}try{$.registry.delete(A),X?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(K){let B=K0(K);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,error:`${z};临时群已确认解散,但本地状态清理失败: ${B}`}}return{ok:!1,error:`${z};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(W.chatId,H):await H()}catch(X){let V=K0(X);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${V}`),{ok:!1,chatId:W.chatId,error:`${V};临时群/session 仍保留`}}},disbandTempSession:async(Q,W)=>{let H=$.chatIdForSession(Q);if(!W||H!==W){let z=`临时群 chat_id 已变化: expected=${W||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,W)){let z=`群 ${W} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}let X=$.registry.get(H);try{if(X)await X.stop("bye 解散",{announce:!1})}catch(z){let A=K0(z);return $.log(`temp-session: stop before disband "${Q}" failed: ${A}`),{ok:!1,error:`${A};无法确认 Session 已停止,未执行删群`}}let V;try{let z=await $.disbandChatForSessionExact(Q,H);V=DH(Q,H,z)}catch(z){let A=K0(z);return $.log(`temp-session: disband "${Q}" failed: ${A}`),{ok:!1,error:`${A};临时群/session 仍保留`}}try{return $.registry.delete(V),X?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(z){let A=K0(z);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${A}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${A}`}}}}}var MH=S(()=>{R1()});var Hq={};import*as a1 from"@larksuiteoapi/node-sdk";import{chmodSync as hB,existsSync as f5,mkdirSync as gB,readFileSync as IB,unlinkSync as e6,writeFileSync as cB}from"node:fs";import{dirname as mB}from"node:path";function o1($,Z){if(X1=Math.max(X1,Z),t6)return t6;v5=!0,n2.close(),w5=g5();try{L2(w5)}catch(J){G(`shutdown alive marker write failed: ${J}`),X1=1}return t6=(async()=>{G(`${$}: staged shutdown begin sessions=${n1.size}`);try{let J=(async()=>{await qH(()=>[...n2.pending(),...EH]);let H=await Promise.allSettled([h5.shutdown(`daemon ${$}`)]),X=await Promise.allSettled([...n1.values()].map((V)=>V.stop(`daemon ${$}`,{announce:!1})));return[...H,...X]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),UH)}),W=await Promise.race([J.then((H)=>{for(let X of H)if(X.status==="rejected")X1=1,G(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(W==="deadline")X1=1,G(`${$}: shutdown deadline ${UH}ms reached; forcing exit`);else G(`${$}: all sessions stopped`)}catch(J){G(`${$}: staged shutdown failed: ${J}`),X1=1}finally{OH(),process.exit(X1)}})(),t6}function TH($){return BH(EH,$)}function NH($,Z="ws"){if(v5)return G(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=pB.accept($);if(!Y.accepted)return G(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{G(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function g5(){let $=new Set;for(let Z of n1.values())if(Z.shouldRevive())$.add(Z.sessionName);for(let Z of d2)$.add(Z);return[...$]}function s6(){L2(g5())}function kH($,Z){return I5.sessionFor($,Z)}async function lB($){return await I5.createTempSession($)}async function iB($,Z){return await I5.disbandTempSession($,Z)}async function dB(){let $=[...new Set(S8())];if($.length===0)return;d2=new Set($),G(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`);try{await Promise.all($.map(async(Z)=>{let J=k1(Z);if(!J){G(`revive: no chatId binding for "${Z}", skip`),d2.delete(Z),s6();return}let Y=kH(J,Z);try{if(await Y.restart(!0))G(`revive: spawned "${Z}" (chat ${J.slice(0,8)}…)`);else G(`revive: "${Z}" did not start`)}catch(Q){G(`revive: restart "${Z}" failed: ${Q}`)}finally{d2.delete(Z),s6()}}))}finally{d2.clear(),s6()}}function nB($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let W=Array.isArray($?.content)?$.content:[];for(let H of W){if(!Array.isArray(H))continue;let X=[];for(let z of H){if(!z||typeof z!=="object")continue;switch(z.tag){case"text":{let A=String(z.text??""),K=Array.isArray(z.style)?z.style:[];if(K.includes("bold"))A=`**${A}**`;if(K.includes("italic"))A=`*${A}*`;if(K.includes("lineThrough")||K.includes("strikethrough"))A=`~~${A}~~`;X.push(A);break}case"a":{let A=String(z.href??""),K=String(z.text??A);X.push(`[${K}](${A})`);break}case"at":{let A=String(z.user_name??z.user_id??"");X.push(`@${A}`);break}case"code_inline":X.push(`\`${String(z.text??"")}\``);break;case"hr":X.push("---");break;case"img":if(z.image_key)Z.push(String(z.image_key));break;case"media":if(z.file_key)J.push({key:String(z.file_key),name:z.file_name});break;case"emotion":break;default:if(typeof z.text==="string")X.push(z.text)}}let V=X.join("");if(V.trim())Y.push(V)}return{markdown:Y.join(`
472
+ exec ${MH(Q.runtime)} ${MH(Q.entry)} "$@"
473
+ `,X=p5(W)?UH(W,"utf8"):null;if(X!==H)BZ(W,H),A(`command: ${X===null?"installed":"updated"} ${W}`);else gB(W,448);return nB(J,Y,Z),iB(Y,Z),W}function iB($,Z){let J=b$($,Z==="win32"?"lodestar-consult.cmd":"lodestar-consult");if(!p5(J))return;try{let Y=UH(J,"utf8");if(!Y.includes("lodestar-consult")&&!Y.includes("consult-cli")){A(`command: obsolete path preserved because ownership is unclear ${J}`);return}IB(J),A(`command: removed obsolete ${J}`)}catch(Y){A(`command: obsolete removal failed (${J}): ${Y}`)}}function dB($,Z,J){if($==="win32")return b$(J??b$(Z,"AppData","Local"),"Lodestar","bin");return b$(Z,".local","bin")}function nB($,Z,J){let Y=J==="win32"?Object.keys($).find((X)=>X.toLowerCase()==="path")??"Path":"PATH",Q=J==="win32"?";":":",W=$[Y]??"",H=(X)=>J==="win32"?X.toLowerCase():X;if(W.split(Q).some((X)=>H(X)===H(Z)))return;$[Y]=W?`${Z}${Q}${W}`:Z}function MH($){return`'${$.replaceAll("'",`'"'"'`)}'`}function FH($){return $.replaceAll('"','""')}var EH=N(()=>{I();I0()});function TH($,Z,J){return $>0&&Z-$>J}async function NH($){if(await $.reply())return!0;if(!$.hasQuestion())return!1;return await $.answerQuestion(),!0}function kH($){let Z=$==="media"?"视频":$==="image"?"图片":"文件";return`❌ 收到的${Z}下载失败,未转交给 Agent。备注:可能是${Z}超过飞书消息资源 100 MB 下载上限。`}function l5($){return typeof $==="string"&&$.length>0?$:void 0}function SH($,Z){if(!Z||typeof Z!=="object")return null;let J=Z;if($==="image"){let H=l5(J.image_key);return H?{key:H,type:"image",displayText:""}:null}if($!=="file"&&$!=="media")return null;let Y=l5(J.file_key);if(!Y)return null;let Q=l5(J.file_name);return{key:Y,type:"file",...Q?{name:Q}:{},displayText:Q?`(${$==="media"?"video":"file"}: ${Q})`:""}}function yH($,Z){return $.add(Z),Z.then(()=>{$.delete(Z)},()=>{$.delete(Z)}),Z}async function xH($){while(!0){let Z=[...$()];if(Z.length===0)return;await Promise.allSettled(Z)}}function oB($){let Z=$?.action?.value??{},J=String(Z.kind??"");if(!J)return"无效操作";if(!aB.has(J))return`不支持的操作: ${J}`;let Y=J==="notify_callback"||J==="notify_reply"||J==="notify_reply_cancel";if(!Y&&!String($?.context?.open_chat_id??""))return"回调缺少 chat_id,操作未执行";if(!Y&&!String($?.context?.open_message_id??""))return"回调缺少原卡 message_id,操作未执行";if(J==="permission"&&!["allow","allow_always","deny"].includes(String(Z.decision??"")))return"无效的权限决定,操作未执行";return null}class d5{tails=new Map;accepting=!0;tryEnqueue($,Z){if(!this.accepting)return{accepted:!1,reason:"closed"};let J=$.trim();if(!J)return{accepted:!1,reason:"invalid-key"};let Q=(this.tails.get(J)??Promise.resolve()).then(Z),W;return W=Q.then(()=>{},()=>{}).finally(()=>{if(this.tails.get(J)===W)this.tails.delete(J)}),this.tails.set(J,W),{accepted:!0,completion:Q}}enqueue($,Z){let J=this.tryEnqueue($,Z);return J.accepted?J.completion:Promise.reject(Error(`per-key actor ${J.reason}`))}close(){this.accepting=!1}isAccepting(){return this.accepting}pending(){return this.tails.values()}}function bH($){let Z=$.now??Date.now;return{accept(J){let Y=Z();return $.actor.tryEnqueue($.key(J),()=>$.execute(J,Y))}}}class n5{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 i5($){if(Array.isArray($))return`[${$.map(i5).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)}:${i5(J)}`).join(",")}}`}function rB($){let Z=$?.action?.value??{},J=String(Z?.kind??"unknown"),Y=String($?.context?.open_chat_id??""),Q=String($?.context?.open_message_id??""),W=null;switch(J){case"menu":W={request_id:Z.request_id};break;case"permission":W={request_id:Z.request_id};break;case"ask":W={tool_use_id:Z.tool_use_id,question_idx:Z.question_idx};break;case"worktree_disband":W={slug:Z.slug};break;case"temp_fork_select":case"temp_back_select":case"temp_resume_select":W={panel_id:Z.panel_id};break;case"tasklist_delete_prompt":case"tasklist_delete_confirm":W={guid:Z.guid};break;case"tasklist_enable":W={guid:Z.guid,project:Z.project,panel_id:Z.panel_id};break;case"token_source_enable":W={source_id:Z.source_id};break;case"agent_identity_page":W={panel_id:Z.panel_id,page:Z.page};break;case"notify_callback":W={notify_id:Z.notify_id};break;case"notify_reply":W={notify_id:Z.notify_id};break;case"notify_reply_cancel":W={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":W={panel_id:Z.panel_id};break;default:W=Z}return`${Y}\x00${Q}\x00${J}\x00${i5(W)}`}function tB($){let Z=String($?.event_id??$?.header?.event_id??$?.event?.event_id??"");return{...Z?{deliveryKey:`event\x00${Z}`}:{},businessKey:`semantic\x00${rB($)}`,...["agent_identity_page","notify_reply"].includes($?.action?.value?.kind)?{repeatable:!0}:{}}}function sB(){return new Promise(($)=>setTimeout($,0))}function Z4($,Z,J){if(Z.deliveryKey)$.complete(Z.deliveryKey);if(J&&!Z.repeatable)$.complete(Z.businessKey);else $.fail(Z.businessKey)}function CH($){let Z=$.afterAck??sB,J=(Q)=>{try{$.onBackgroundError?.(Q)}catch{}},Y=async(Q)=>{try{await Q()}catch(W){J(W)}};return{accept(Q){if(!$.actor.isAccepting())return $.responses.closed(Q);let W=oB(Q);if(W)return $.responses.invalid(Q,W);let H=tB(Q),X=H.deliveryKey?[H.deliveryKey,H.businessKey]:[H.businessKey],V=$.deduper.claimAll(X);if(V==="inflight")return $.responses.inflight(Q);if(V==="completed")return $.responses.completed(Q);let z=$.actor.tryEnqueue($.scope(Q),async()=>{try{await Z()}catch(B){$.deduper.failAll(X),J(B);return}let G;try{G=await $.execute(Q)}catch(B){Z4($.deduper,H,!0),await Y(()=>$.presentExecutionFailure(Q,B));return}await Y(async()=>{try{await $.present(Q,G)}catch(B){await $.presentPresentationFailure(Q,B)}});let _;try{_=$.completion(Q,G)}catch(B){Z4($.deduper,H,!1),J(B);return}if(_){let B=_.then((q)=>{Z4($.deduper,H,q==="complete")},(q)=>{Z4($.deduper,H,!1),J(q)});$.track(B);return}Z4($.deduper,H,$.businessSucceeded(Q,G))});if(!z.accepted)return $.deduper.failAll(X),$.responses.closed(Q);return $.track(z.completion),z.completion.catch(J),$.responses.accepted(Q)}}}var aB;var wH=N(()=>{aB=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","notify_callback","notify_reply","notify_reply_cancel"])});function K$($){return $ instanceof Error?$.message:String($)}function fH($,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 vH($){let Z=(Q,W)=>{let H=$.registry.get(Q);if(H&&H.sessionName!==W)throw Error(`chat ${Q} is already owned by session "${H.sessionName}", not "${W}"`);if(!H)H=$.createSession(W,Q),$.registry.set(Q,H);return H};return{sessionFor:Z,createTempSession:async(Q)=>{let W;try{if(z0(Q.launch,Q.routing.provider,Q.workDir),Q.launch.kind==="resume")throw Error("temporary groups must start fresh or fork; resume is not allowed");if(W=await $.ensureChatForSession(Q.chatName,Q.userOpenId),!W.created)return{ok:!1,chatId:W.chatId,error:"临时会话必须使用新群;既有群保留,未执行加入、启动或删除"}}catch(X){let V=K$(X);return $.log(`temp-session: create "${Q.chatName}" failed: ${V}`),{ok:!1,error:V}}let H=async()=>{let X=null;try{if($.registerTempSessionLease(Q.chatName,W.chatId),X=Z(W.chatId,Q.chatName),X.isRunning())return{ok:!1,error:`${Q.chatName} 已有会话在跑,先 bye 解散再重试`};if(X.workDir!==Q.workDir)throw Error(`临时群 cwd 不匹配: source=${Q.workDir} target=${X.workDir}`);if(X.applyConversationRouting(Q.routing),!(Q.launch.kind==="fork"?await X.startForked(Q.launch,{announce:!1}):await X.start({announce:!1})))throw Error(`${X.backendLabel()} 启动失败`);return $.replaceTurnAnchors(Q.chatName,Q.seedAnchors??[],Q.branchBase),{ok:!0,chatId:W.chatId}}catch(V){let z=K$(V);if($.log(`temp-session: initialize "${Q.chatName}" failed: ${z}`),X)try{await X.stop("临时群启动失败清理",{announce:!1})}catch(_){let B=K$(_);return $.log(`temp-session: failed-create stop "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};无法确认 Session 已停止,临时群/session 仍保留: ${B}`}}if(!W.created)return{ok:!1,error:`${z};既有群保留,未执行删除`};let G;try{let _=await $.disbandChatForSessionExact(Q.chatName,W.chatId);G=fH(Q.chatName,W.chatId,_)}catch(_){let B=K$(_);return $.log(`temp-session: create cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,chatId:W.chatId,error:`${z};自动解散失败,临时群/session 仍保留: ${B}`}}try{$.registry.delete(G),X?.dispose(),$.clearSessionConversationState(Q.chatName)}catch(_){let B=K$(_);return $.log(`temp-session: local cleanup "${Q.chatName}" failed: ${B}`),{ok:!1,error:`${z};临时群已确认解散,但本地状态清理失败: ${B}`}}return{ok:!1,error:`${z};本次新建的临时群已确认解散`}}};try{return $.runExclusive?await $.runExclusive(W.chatId,H):await H()}catch(X){let V=K$(X);return $.log(`temp-session: target actor "${Q.chatName}" failed: ${V}`),{ok:!1,chatId:W.chatId,error:`${V};临时群/session 仍保留`}}},disbandTempSession:async(Q,W)=>{let H=$.chatIdForSession(Q);if(!W||H!==W){let z=`临时群 chat_id 已变化: expected=${W||"-"} bound=${H??"-"}`;return $.log(`temp-session: disband identity rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}if(!$.hasTempSessionLease(Q,W)){let z=`群 ${W} 没有 Lodestar 临时会话 lease,拒绝解散`;return $.log(`temp-session: disband lease rejected "${Q}": ${z}`),{ok:!1,error:`${z};未执行停止或删群`}}let X=$.registry.get(H);try{if(X)await X.stop("bye 解散",{announce:!1})}catch(z){let G=K$(z);return $.log(`temp-session: stop before disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};无法确认 Session 已停止,未执行删群`}}let V;try{let z=await $.disbandChatForSessionExact(Q,H);V=fH(Q,H,z)}catch(z){let G=K$(z);return $.log(`temp-session: disband "${Q}" failed: ${G}`),{ok:!1,error:`${G};临时群/session 仍保留`}}try{return $.registry.delete(V),X?.dispose(),$.clearSessionConversationState(Q),{ok:!0}}catch(z){let G=K$(z);return $.log(`temp-session: local cleanup after disband "${Q}" failed: ${G}`),{ok:!1,error:`临时群已确认解散,但本地状态清理失败: ${G}`}}}}}var hH=N(()=>{D1()});var Fq={};import*as J2 from"@larksuiteoapi/node-sdk";import{chmodSync as eB,existsSync as o5,mkdirSync as $q,readFileSync as Zq,unlinkSync as _6,writeFileSync as Jq}from"node:fs";import{dirname as Yq}from"node:path";function Y2($,Z){if(A1=Math.max(A1,Z),G6)return G6;t5=!0,Z2.close(),r5=$Z();try{E2(r5)}catch(J){A(`shutdown alive marker write failed: ${J}`),A1=1}return G6=(async()=>{A(`${$}: staged shutdown begin sessions=${K1.size}`);try{let J=(async()=>{await xH(()=>[...Z2.pending(),...mH]);let H=await Promise.allSettled([s5.shutdown(`daemon ${$}`)]),X=await Promise.allSettled([...K1.values()].map((V)=>V.stop(`daemon ${$}`,{announce:!1})));return[...H,...X]})(),Y=null,Q=new Promise((H)=>{Y=setTimeout(()=>H("deadline"),IH)}),W=await Promise.race([J.then((H)=>{for(let X of H)if(X.status==="rejected")A1=1,A(`shutdown session stop failed: ${X.reason}`);return"stopped"}),Q]);if(Y)clearTimeout(Y);if(W==="deadline")A1=1,A(`${$}: shutdown deadline ${IH}ms reached; forcing exit`);else A(`${$}: all sessions stopped`)}catch(J){A(`${$}: staged shutdown failed: ${J}`),A1=1}finally{cH(),process.exit(A1)}})(),G6}function e5($){return yH(mH,$)}function uH($,Z="ws"){if(t5)return A(`${Z}: reject inbound message: daemon shutdown in progress`),!1;let J=String($?.message?.chat_id??""),Y=Wq.accept($);if(!Y.accepted)return A(`${Z}: reject inbound message${J?"":" without chat_id"}: actor ${Y.reason}`),!1;return Y.completion.catch((Q)=>{A(`${Z}: handleMessage rejected chat=${J.slice(0,8)}…: ${Q}`)}),!0}function $Z(){let $=new Set;for(let Z of K1.values())if(Z.shouldRevive())$.add(Z.sessionName);for(let Z of J4)$.add(Z);return[...$]}function A6(){E2($Z())}function pH($,Z){return ZZ.sessionFor($,Z)}async function Hq($){return await ZZ.createTempSession($)}async function Xq($,Z){return await ZZ.disbandTempSession($,Z)}async function Vq(){let $=[...new Set(p7())];if($.length===0)return;J4=new Set($),A(`revive: ${$.length} session(s) marked alive on shutdown: ${$.join(", ")}`);try{await Promise.all($.map(async(Z)=>{let J=p4(Z);if(!J){A(`revive: no chatId binding for "${Z}", skip`),J4.delete(Z),A6();return}let Y=pH(J,Z);try{if(await Y.restart(!0))A(`revive: spawned "${Z}" (chat ${J.slice(0,8)}…)`);else A(`revive: "${Z}" did not start`)}catch(Q){A(`revive: restart "${Z}" failed: ${Q}`)}finally{J4.delete(Z),A6()}}))}finally{J4.clear(),A6()}}function zq($){let Z=[],J=[],Y=[],Q=typeof $?.title==="string"?$.title.trim():"";if(Q)Y.push(`# ${Q}`);let W=Array.isArray($?.content)?$.content:[];for(let H of W){if(!Array.isArray(H))continue;let X=[];for(let z of H){if(!z||typeof z!=="object")continue;switch(z.tag){case"text":{let G=String(z.text??""),_=Array.isArray(z.style)?z.style:[];if(_.includes("bold"))G=`**${G}**`;if(_.includes("italic"))G=`*${G}*`;if(_.includes("lineThrough")||_.includes("strikethrough"))G=`~~${G}~~`;X.push(G);break}case"a":{let G=String(z.href??""),_=String(z.text??G);X.push(`[${_}](${G})`);break}case"at":{let G=String(z.user_name??z.user_id??"");X.push(`@${G}`);break}case"code_inline":X.push(`\`${String(z.text??"")}\``);break;case"hr":X.push("---");break;case"img":if(z.image_key)Z.push(String(z.image_key));break;case"media":if(z.file_key)J.push({key:String(z.file_key),name:z.file_name});break;case"emotion":break;default:if(typeof z.text==="string")X.push(z.text)}}let V=X.join("");if(V.trim())Y.push(V)}return{markdown:Y.join(`
383
474
 
384
- `),imageKeys:Z,fileKeys:J}}async function oB($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",W=J.message_id;if(W&&i1.has(W))return;if(W){if(i1.add(W),i1.size>200){let P=[...i1];i1.clear();for(let j of P.slice(-100))i1.add(j)}}let H=Number(J.create_time??0);if(AH(H,Z,aB)){if(G(`drop stale message ${W} ageAtReceipt=${Math.round((Z-H)/1000)}s`),W)T$(W,"CrossMark");return}let X=J.chat_id,V={};try{V=JSON.parse(J.content??"{}")}catch{}let z=J.message_type==="text"?V.text??"":"";if(typeof z==="string"&&z.startsWith("[DEBUG]")){try{cB(s2,JSON.stringify({chat_id:X,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:W??""},null,2)),G(`debug: seeded inject context chat=${X.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(j){G(`debug: seed context failed: ${j}`)}let P=z.slice(7);V.text=P,J.content=JSON.stringify(V)}let A=Y$.get(X);if(!A)await P2(),A=Y$.get(X);if(!A)A=await f8(X)??void 0;if(!A){G(`unknown chat ${X}, dropping message`),await N(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let K=M2(A);E1(K,X);let B=kH(X,K),q={};try{q=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,R="",D=[];if(L==="text")R=(q.text??"").trim();else if(L==="post"){let P=nB(q);R=P.markdown.trim();for(let j of P.imageKeys){let O=await D2(J.message_id,j,"image");if(O)D.push(O)}for(let j of P.fileKeys){let O=await D2(J.message_id,j.key,"file",j.name);if(O)D.push(O)}}if(L==="text"&&R){if(await B.runCommand(R,Q))return}if(L==="text"&&R&&await B.consumeModelCustomMessage(R,Q))return;if(L==="text"&&R&&B.hasPendingAsk()){await B.onAskMessageAnswer(R,Q,W??"");return}let U=_H(L,q);if(U){let P=await D2(J.message_id,U.key,U.type,U.name);if(!P){await N(X,KH(L));return}if(D.push(P),!R&&U.displayText)R=U.displayText}if(!R&&D.length===0){G(`drop empty message ${W} type=${L}`);return}if(await B.onMultiMessageInbound(R,D,Q,W??""))return;await B.onUserMessage(R||"(empty)",D,Q,W??"")}function $9($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",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:"通知反馈"}[$]??$}function rB($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function Q$($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function V1($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function d1($){return Q$($.card?w$($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function z1($,Z){if(!$){G(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await C($,Z))G(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function tB($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=$9(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),W=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=rB(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&W)try{await Q0(W,H);return}catch(q){G(`card-action: ${J} original-card update failed: ${q instanceof Error?q.message:q}`),await z1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await z1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let V=Z?.toast,z=typeof V?.content==="string"&&V.content.trim()?V.content.trim():`${Y}已完成`,A=J==="permission"&&String($?.action?.value?.decision??"")==="deny",K=Z?.__businessOk===!1||V?.type==="error"&&!A;if(!K&&new Set(["permission","ask","token_source_enable"]).has(J))return;await z1(Q,`${K?"❌":"✅"} ${Y}: ${z}`)}async function sB($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await z1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${$9(J)}失败: ${Y}`)}function $q($){return eB.accept($)}async function Zq($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Y=$?.context?.open_chat_id??"",Q=$?.operator?.open_id??"";if(J.kind==="notify_callback")return await Jq(J,Y,Q);let W=n1.get(Y);if(!W)return Q$({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let H=String(J.decision??"");if(!["allow","allow_always","deny"].includes(H))return{toast:{type:"error",content:"无效的权限决定"}};let X=await W.onPermissionDecision(J.request_id,H,Q);return Q$({toast:{type:X.ok?H==="deny"?"error":"success":"error",content:X.message}},X.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await W.onUserMessage(`(menu choice ${H+1})`),Q$(w$(O0({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let V=X instanceof Error?X.message:String(X);return Q$(w$(O0({title:"\uD83D\uDCCB 菜单选择",message:V,ok:!1})),!1)}}case"provider_select":{let H=await W.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return d1(H)}case"model_select":{let H=await W.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return d1(H)}case"model_custom_prompt":{let H=await W.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return d1(H)}case"model_panel_cancel":{let H=await W.onModelPanelCancel(String(J.panel_id??""));return d1(H)}case"model_effort_select":{let H=await W.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return d1(H)}case"ask":{if(J.custom){let V=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",z=await W.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,V,Q);return Q$({toast:{type:z?"success":"error",content:z?"已回答":V.trim()?"问题已失效或答案未被接受":"请输入答案"}},z)}let H=await W.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return Q$({toast:{type:H?"success":"error",content:H?"已回答":"问题已失效或选项无效"}},H)}case"worktree_disband":{let H=await W.onWorktreeDisband(String(J.slug??""));return Q$(w$(H.card),H.ok)}case"temp_fork_select":{let H=await W.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return Q$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:w$(O0({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await W.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return Q$(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:w$(O0({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await W.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return Q$({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return Q$(w$(j7({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await W.onTasklistEnable();return Q$(w$(H.card),H.ok)}case"tasklist_delete_prompt":{let H=W.onTasklistDeletePrompt(String(J.guid??""));return Q$(w$(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await W.onTasklistDeleteConfirm(String(J.guid??""));return Q$(w$(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (e7(),s7));return await H(W,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return d1(W.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function Jq($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let W=l6(Y);if(!W)return G(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(W.unknownAt)return V1(W,Q$({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${W.unknownReason?`: ${W.unknownReason}`:""}`}},!0));if(W.resolvedAt)return V1(W,{toast:{type:"info",content:"已处理过"}});if(DW(Y))return V1(W,{toast:{type:"info",content:"处理中…"}});let H=W.buttons.find((z)=>z.id===Q);if(!H)return G(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),V1(W,Q$({toast:{type:"error",content:"未知按钮"}},!1));if(!W.callbackUrl){try{L5(W.notifyId,H.id,J)}catch(z){return V1(W,Q$({toast:{type:"error",content:`保存反馈结果失败: ${z instanceof Error?z.message:z}`}},!1))}return G(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),V1(W,{...w$(i6(W,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}jW(W.notifyId);let X=TH(Yq(W,H,J));X.catch((z)=>{G(`notify-callback: notify_id=${W.notifyId.slice(0,12)}… phase-2 rejected: ${z instanceof Error?z.message:z}`)});let V=X.then((z)=>z==="retry"?"retry":"complete").catch(()=>"retry");return V1(W,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:V})}async function Yq($,Z,J){try{let Y=i6($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await Q0($.messageId,Y)}catch(X){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${X instanceof Error?X.message:X}`)}let Q=await EW($,Z,J),W=Q.ok?"complete":"retry",H;if(Q.ok){let X=OW($.notifyId,Z.id,J);if(X.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{W="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:X.detail},G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${X.detail}`);try{await z1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${X.detail}`)}catch(V){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${V instanceof Error?V.message:V}`)}}}else H={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Q.detail};try{let X=i6($,H);await Q0($.messageId,X)}catch(X){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${X instanceof Error?X.message:X}`);try{await z1($.chatId,`⚠️ 通知反馈${W==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${X instanceof Error?X.message:X}`)}catch(V){G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${V instanceof Error?V.message:V}`)}}return G(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${W==="complete"?"delivered":W==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),W}finally{MW($.notifyId)}}function b5($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function Qq(){if(process.platform==="win32"){G("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){G("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(f5(C0))e6(C0)}catch{}try{Bun.serve({unix:C0,fetch:async($)=>{if($.method!=="POST")return new Response("use POST",{status:405});if(v5)return new Response("daemon shutdown in progress",{status:503});let Z={};try{Z=await $.json()}catch{return new Response("bad json",{status:400})}if(!f5(s2))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let J={};try{J=JSON.parse(IB(s2,"utf8"))}catch(X){return new Response(`ctx read failed: ${X}`,{status:500})}let Y=String(Z.text??"");if(!Y)return new Response("text required",{status:400});let Q=`【自动化测试】:${Y}`,W=await N(J.chat_id,Q);if(!W)return new Response("sendText failed — see daemon log",{status:502});let H={sender:{sender_id:{open_id:J.sender_open_id}},message:{message_id:W,chat_id:J.chat_id,message_type:"text",content:JSON.stringify({text:Y}),create_time:String(Date.now())}};if(G(`debug: inject text=${JSON.stringify(Y).slice(0,80)} msg_id=${W}`),!NH(H,"debug"))return new Response("daemon shutdown in progress",{status:503});return new Response(JSON.stringify({ok:!0,msg_id:W}),{headers:{"content-type":"application/json"}})}});try{hB(C0,384)}catch{}G(`debug: inject socket listening at ${C0}`)}catch($){G(`debug: socket bind failed: ${$}`)}}async function Wq(){G(`lodestar-daemon: pid ${process.pid} starting`);let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (r7(),tY));$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (G$(),X3));await Z(),q8(),P8(),D8(),M8(),O8(),await P2(),setInterval(()=>{P2()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (Y5(),J5));try{await J()}catch(k){G(`tasklist deletion reconcile failed: ${k instanceof Error?k.message:k}`)}let Y,Q=Date.now(),W=0,H=!1,X=null,V=1500,z=90000,A=600000,K=3,B=null,q=0,L="",R=!1,D=(k)=>{G(`[ws] rebuild requested before WS init — ${k}`)},U=(k,u=0,E=!1)=>{let y=Date.now()+u;if(B){if(R||=E,y>=q){G(`[ws] rebuild already scheduled — ${k}`);return}clearTimeout(B)}q=y,L=k,R=E,B=setTimeout(()=>{let f=L,M$=R;B=null,q=0,L="",R=!1,D(f,M$)},u)},P={error:(k)=>G(`[ws-sdk error] ${b5(k)}`),warn:(k)=>{let u=b5(k);if(G(`[ws-sdk warn] ${u}`),u.includes("no pong/inbound"))U("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<A)},info:(k)=>G(`[ws-sdk] ${b5(k)}`),debug:(k)=>{},trace:(k)=>{}},j=new a1.EventDispatcher({}),O=()=>{if(Q=Date.now(),W=0,X)clearTimeout(X),X=null};j.register({"im.message.receive_v1":async(k)=>{if(O(),!NH(k))throw Error("daemon shutdown in progress")}}),j.register({"card.action.trigger":async(k)=>{return O(),$q(k)}});let b=()=>new a1.WSClient({appId:v.feishu.app_id,appSecret:v.feishu.app_secret,loggerLevel:a1.LoggerLevel.info,logger:P,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>G("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>m(),onError:(k)=>D(`SDK onError: ${k?.message??k}`)});D=(k,u=!1)=>{if(H){G(`[ws] rebuild skipped (already rebuilding) — ${k}`);return}if(B)clearTimeout(B),B=null,q=0;H=!0,W++,G(`[ws] rebuild #${W} (fresh WSClient) — ${k}`);let E=Y;try{E?.close({force:!0})}catch(y){G(`[ws] rebuild: old close failed: ${y}`)}if(Y=b(),Y.start({eventDispatcher:j}).catch((y)=>{G(`[ws] rebuild start failed: ${y}`),U(`fresh client start failed: ${y}`,V,u)}),H=!1,u)x()};let x=()=>{if(X)clearTimeout(X);let k=Date.now();X=setTimeout(()=>{if(X=null,Q>=k){W=0;return}if(W>=K){G(`[ws] STILL deaf after ${K} fresh rebuilds — auto-heal exhausted, `+"leaving last client up (no process exit). Restart the configured service or run lodestar-stop && lodestar-daemon"),W=0;return}D(`verify: no event ${Math.round((Date.now()-k)/1000)}s after rebuild`,!0)},z)},m=()=>{let k=Date.now()-Q<A;G("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${k})`),W=0,U("post-reconnect precaution",V,k)};Y=b(),Y.start({eventDispatcher:j}).catch((k)=>{G(`[ws] initial start failed: ${k}`),U(`initial start failed: ${k}`,V,!1)}),G(`lodestar-daemon: WS start requested, watching ${Y$.size} groups`);let h=15000,I=2,T=0;setInterval(()=>{let{state:k}=Y.getConnectionStatus();if(k==="connected"){T=0;return}if(k==="failed"||k==="idle"){T=0,D(`watchdog: state=${k}`);return}if(T++,G(`[ws] watchdog: state=${k} (${T}/${I})`),T>=I)T=0,D(`watchdog: stuck in '${k}' ~${Math.round(h*I/1000)}s`)},h),Qq(),FW(),yW({bind:v.notify.bind,port:v.notify.port,extraHandler:(k,u,E)=>QH(k,u,E,{service:h5,authorizeSession:(y)=>{for(let f of n1.values())if(f.acceptsAgentCapability(y))return f;return null}})}),zH(),bW(),hW(),await dB()}var FH=!1,v5=!1,t6=null,X1=0,w5=null,UH=15000,OH=()=>{if(FH)return;FH=!0;try{let $=w5??g5();if(L2($),$.length>0)G(`alive marker: [${$.join(", ")}]`)}catch($){G(`alive marker write failed: ${$}`)}try{e6(N$)}catch{}try{e6(C0)}catch{}},n1,h5,d2,n2,uB,EH,pB,I5,aB=30000,i1,eB;var SH=S(()=>{qW();o();f$();P5();D5();D5();fW();tW();WH();U5();GH();U$();g();R$();V9();PH();MH();{let $=e2(N$);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(f5(N$))try{e6(N$)}catch{}}gB(mB(N$),{recursive:!0});n5(N$);process.on("exit",OH);process.on("SIGTERM",()=>{o1("SIGTERM",0)});process.on("SIGINT",()=>{o1("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{o1("SIGBREAK",0)});process.on("unhandledRejection",($)=>{G(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),o1("unhandledRejection",1)});process.on("uncaughtException",($)=>{G(`uncaughtException: ${$.stack??$.message}`),o1("uncaughtException",1)});n1=new Map,h5=new E5,d2=new Set,n2=new x5,uB=new C5(30000),EH=new Set,pB=RH({actor:n2,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>oB($,Z)});I5=jH({registry:n1,createSession:($,Z)=>new H1($,Z,{onLifecycleChange:s6,onCreateTempSession:lB,onDisbandTempSession:iB,onCancelAgentRuns:(J,Y,Q)=>h5.cancelSessionRuns(J,Y,Q)}),ensureChatForSession:x8,disbandChatForSessionExact:b8,chatIdForSession:k1,clearSessionConversationState:k8,registerTempSessionLease:R8,hasTempSessionLease:L8,replaceTurnAnchors:c$,runExclusive:($,Z)=>n2.enqueue($,Z),log:G});i1=new Set;eB=LH({actor:n2,deduper:uB,scope:($)=>{if(String($?.action?.value?.kind??"").startsWith("agent_identity_"))return"__agent_identities_global__";return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:Zq,present:tB,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");G(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await sB($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");G(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await z1(String($?.context?.open_chat_id??""),`⚠️ ${$9(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__cardActionCompletion;return J&&typeof J.then==="function"?J:null},track:($)=>{TH($)},onBackgroundError:($)=>{G(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${$9(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}})}});Wq().catch(($)=>{G(`boot fatal: ${$}`),o1("boot fatal",1)})});R$();V9();import{existsSync as yH,unlinkSync as Xq}from"node:fs";var d$={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function Vq(){if(!yH(q$)){if(process.stdin.isTTY){console.log(),console.log(`${d$.bold}${d$.yellow}Lodestar: 未找到配置, 启动安装向导...${d$.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (YZ(),JZ));await Z();return}console.error(`${d$.red}Lodestar: 未找到配置 ${q$}${d$.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${d$.green}lodestar-setup${d$.reset} 完成首次配置 (或直接运行 ${d$.green}lodestar-daemon${d$.reset} 也会触发同一个向导)。`),process.exit(1)}let $=e2(N$);if($.state==="exit")console.error(`${d$.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${d$.reset}`),console.error(" • 想看日志:"+(process.platform==="win32"?" %LOCALAPPDATA%\\Lodestar\\daemon-YYYY-MM-DD.log":" ~/.local/share/lodestar/daemon-YYYY-MM-DD.log")),console.error(" • 想停: 任务管理器结束 pid 上面那个号 (Windows) / `kill "+$.pid+"` (Linux/macOS)"),console.error(` • 误判 / 已经死了: 手删 ${N$} 后再跑`),process.exit(1);if(yH(N$))try{Xq(N$)}catch{}await Promise.resolve().then(() => (SH(),Hq))}Vq().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});
475
+ `),imageKeys:Z,fileKeys:J}}async function Aq($,Z=Date.now()){let J=$?.message;if(!J)return;let Q=($?.sender?.sender_id??$?.event?.sender?.sender_id??J?.sender?.sender_id)?.open_id??"",W=J.message_id;if(W&&e1.has(W))return;if(W){if(e1.add(W),e1.size>200){let D=[...e1];e1.clear();for(let E of D.slice(-100))e1.add(E)}}let H=Number(J.create_time??0);if(TH(H,Z,Gq)){if(A(`drop stale message ${W} ageAtReceipt=${Math.round((Z-H)/1000)}s`),W)T0(W,"CrossMark");return}let X=J.chat_id,V={};try{V=JSON.parse(J.content??"{}")}catch{}let z=J.message_type==="text"?V.text??"":"";if(typeof z==="string"&&z.startsWith("[DEBUG]")){try{Jq(X4,JSON.stringify({chat_id:X,sender_open_id:Q,seeded_at:new Date().toISOString(),seeded_msg_id:W??""},null,2)),A(`debug: seeded inject context chat=${X.slice(0,8)}… sender=${Q.slice(0,8)}…`)}catch(E){A(`debug: seed context failed: ${E}`)}let D=z.slice(7);V.text=D,J.content=JSON.stringify(V)}let G=Q0.get(X);if(!G)await T2(),G=Q0.get(X);if(!G)G=await a7(X)??void 0;if(!G){A(`unknown chat ${X}, dropping message`),await T(X,"❌ 无法识别群名。请确认:① 机器人已被拉进本群;② 群已设置名称(未命名群拿不到群名,无法映射项目目录)。设置后再发一条消息即可。");return}let _=t7(G);S1(_,X);let B=pH(X,_),q={};try{q=JSON.parse(J.content??"{}")}catch{}let L=J.message_type,P="",R=!1,O=[];if(L==="text")P=(q.text??"").trim();else if(L==="post"){let D=zq(q);R=D.imageKeys.length>0||D.fileKeys.length>0,P=D.markdown.trim();for(let E of D.imageKeys){let x=await N2(J.message_id,E,"image");if(x)O.push(x)}for(let E of D.fileKeys){let x=await N2(J.message_id,E.key,"file",E.name);if(x)O.push(x)}}if(L==="text"&&P){if(await B.runCommand(P,Q))return}if((L==="text"||L==="post")&&P&&!R&&await NH({reply:()=>K6.consume({chatId:X,openId:Q,messageId:W??"",text:P,createTime:H,parentId:J.parent_id}),hasQuestion:()=>B.hasPendingAsk(),answerQuestion:()=>B.onAskMessageAnswer(P,Q,W??"")}))return;if(L==="text"&&P&&await B.consumeModelCustomMessage(P,Q))return;let j=SH(L,q);if(j){let D=await N2(J.message_id,j.key,j.type,j.name);if(!D){await T(X,kH(L));return}if(O.push(D),!P&&j.displayText)P=j.displayText}if(!P&&O.length===0){A(`drop empty message ${W} type=${L}`);return}if(await B.onMultiMessageInbound(P,O,Q,W??""))return;await B.onUserMessage(P||"(empty)",O,Q,W??"")}function B6($){return{permission:"权限决定",menu:"菜单选择",provider_select:"账号选择",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 _q($){return $?.card?.type==="raw"&&$.card.data&&typeof $.card.data==="object"?$.card.data:null}function r($,Z,J){return{...$,__businessOk:Z,...J?{__businessMessage:J}:{}}}function B$($,Z){return{...Z,__cardActionMessageId:$.messageId,__cardActionChatId:$.chatId}}function $2($){return r($.card?v0($.card):{toast:{type:$.ok?"success":"error",content:$.message}},$.ok)}async function _1($,Z){if(!$){A(`card-action: cannot send receipt without chat_id: ${Z}`);return}if(!await C($,Z))A(`card-action: visible receipt MISS chat=${$.slice(0,8)}… text=${Z.slice(0,120)}`)}async function Kq($,Z){if(Z?.__cardActionPresented)return;let J=String($?.action?.value?.kind??"unknown"),Y=B6(J),Q=String(Z?.__cardActionChatId??$?.__cardActionChatId??$?.context?.open_chat_id??""),W=String(Z?.__cardActionMessageId??$?.context?.open_message_id??""),H=_q(Z),X=Z?.__businessOk===!1&&typeof Z?.__businessMessage==="string"?` 业务失败: ${Z.__businessMessage.replace(/\s+/g," ").trim().slice(0,300)}。`:"";if(H&&W)try{await r0(W,H);return}catch(q){A(`card-action: ${J} original-card update failed: ${q instanceof Error?q.message:q}`),await _1(Q,`⚠️ ${Y}已处理,但原卡更新失败。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":"请重新打开操作面板。"}`);return}if(H){await _1(Q,`⚠️ ${Y}已处理,但回调缺少原卡 message_id,无法更新。${X}${J==="temp_resume_select"?"请发送 rs 查看当前状态。":""}`);return}if(J==="notify_callback"&&Z?.__cardActionCompletion)return;let V=Z?.toast,z=typeof V?.content==="string"&&V.content.trim()?V.content.trim():`${Y}已完成`,G=J==="permission"&&String($?.action?.value?.decision??"")==="deny",_=Z?.__businessOk===!1||V?.type==="error"&&!G;if(!_&&new Set(["permission","ask","token_source_enable"]).has(J))return;await _1(Q,`${_?"❌":"✅"} ${Y}: ${z}`)}async function Bq($,Z){let J=String($?.action?.value?.kind??"unknown"),Y=Z instanceof Error?Z.message:String(Z);await _1(String($?.__cardActionChatId??$?.context?.open_chat_id??""),`❌ ${B6(J)}失败: ${Y}`)}function Lq($){return qq.accept($)}async function Pq($){let Z=$?.action,J=Z?.value;if(!J?.kind)return;let Y=$?.context?.open_chat_id??"",Q=$?.operator?.open_id??"";if(J.kind==="notify_callback"||J.kind==="notify_reply"||J.kind==="notify_reply_cancel"){let H=String(J.notify_id??""),X=G$(H);if(X)$.__cardActionChatId=X.chatId;if(J.kind==="notify_callback")return await jq(J,Y,Q);let V=J.kind==="notify_reply"?await K6.open(H,Y,Q):await K6.cancel(H,String(J.reply_id??""),Y,Q),z=r({toast:{type:V.ok?"success":"error",content:V.message},__cardActionPresented:V.presented===!0},V.ok);return X?B$(X,z):z}let W=K1.get(Y);if(!W)return r({toast:{type:"error",content:"会话不存在,请先发消息启动"}},!1);switch(J.kind){case"permission":{let H=String(J.decision??"");if(!["allow","allow_always","deny"].includes(H))return{toast:{type:"error",content:"无效的权限决定"}};let X=await W.onPermissionDecision(J.request_id,H,Q);return r({toast:{type:X.ok?H==="deny"?"error":"success":"error",content:X.message}},X.ok)}case"menu":{let H=Number(J.choice??-1);try{if(!Number.isInteger(H)||H<0)throw Error("无效的菜单选项");return await W.onUserMessage(`(menu choice ${H+1})`),r(v0(T$({title:"\uD83D\uDCCB 菜单选择",message:`已选择第 ${H+1} 项`,ok:!0})),!0)}catch(X){let V=X instanceof Error?X.message:String(X);return r(v0(T$({title:"\uD83D\uDCCB 菜单选择",message:V,ok:!1})),!1)}}case"provider_select":{let H=await W.onProviderSelect(String(J.source_id??""),String(J.panel_id??""));return $2(H)}case"model_select":{let H=await W.onModelSelect(String(J.model??""),String(J.panel_id??""),Q,J);return $2(H)}case"model_custom_prompt":{let H=await W.onModelCustomPrompt(String(J.source_id??""),String(J.panel_id??""),String($?.context?.open_message_id??""));return $2(H)}case"model_panel_cancel":{let H=await W.onModelPanelCancel(String(J.panel_id??""));return $2(H)}case"model_effort_select":{let H=await W.onModelEffortSelect(String(J.model??""),String(J.effort??""),String(J.panel_id??""),Q,String(J.provider??""));return $2(H)}case"ask":{let H=W.askBlockReason(String(J.tool_use_id??""));if(H)return r({toast:{type:"error",content:H}},!1);if(J.custom){let z=(Z?.form_value??Z?.input??{})?.custom_answer??Z?.input_value??"",G=await W.onAskCustomAnswer(J.tool_use_id,J.question_idx??0,z,Q);return r({toast:{type:G?"success":"error",content:G?"已回答":z.trim()?"问题已失效或答案未被接受":"请输入答案"}},G)}let X=await W.onAskAnswer(J.tool_use_id,J.question_idx??0,J.option_idx,Q);return r({toast:{type:X?"success":"error",content:X?"已回答":"问题已失效或选项无效"}},X)}case"worktree_disband":{let H=await W.onWorktreeDisband(String(J.slug??""));return r(v0(H.card),H.ok)}case"temp_fork_select":{let H=await W.onForkSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return r(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:v0(T$({title:"\uD83D\uDD31 会话分叉",message:H.message,ok:H.ok})),H.ok)}case"temp_back_select":{let H=await W.onBackSelect(String(J.panel_id??""),String(J.choice_id??""),Q);return r(H.replaceCard===!1?{toast:{type:"error",content:H.message}}:v0(T$({title:"⏪ 会话回滚",message:H.message,ok:H.ok})),H.ok)}case"temp_resume_select":{let H=await W.onResumeSelect(String(J.panel_id??""),String(J.choice_id??""),Q);if(H.replaceCard===!1)return r({toast:{type:"error",content:H.message}},H.ok);if(!H.resumePresentation)throw Error("rs selection result missing trusted presentation snapshot");return r(v0(w8({...H.resumePresentation,message:H.message,ok:H.ok})),H.ok,H.message)}case"tasklist_enable":{let H=await W.onTasklistEnable();return r(v0(H.card),H.ok)}case"tasklist_delete_prompt":{let H=W.onTasklistDeletePrompt(String(J.guid??""));return r(v0(H.card),H.ok)}case"tasklist_delete_confirm":{let H=await W.onTasklistDeleteConfirm(String(J.guid??""));return r(v0(H.card),H.ok)}case"token_source_enable":{let{onTokenSourceEnable:H}=await Promise.resolve().then(() => (j5(),P5));return await H(W,String(J.source_id??"")),{toast:{type:"info",content:"已处理"}}}case"agent_identity_page":return $2(W.onAgentIdentityPage(String(J.panel_id??""),J.page,Q))}return{toast:{type:"info",content:"unknown action"}}}async function jq($,Z,J){let Y=String($?.notify_id??""),Q=String($?.button_id??"");if(!Y)return{toast:{type:"error",content:"回调缺少 notify_id"}};let W=G$(Y);if(!W)return A(`notify-callback: notify_id=${Y.slice(0,12)}… not found (expired or pre-restart)`),{toast:{type:"error",content:"通知已过期或已移除"}};if(W.unknownAt)return B$(W,r({toast:{type:"error",content:`外部回调可能已成功,但本地确认状态未知,已禁止自动重试${W.unknownReason?`: ${W.unknownReason}`:""}`}},!0));if(W.resolvedAt)return B$(W,{toast:{type:"info",content:"已处理过"}});if(u1(Y))return B$(W,{toast:{type:"info",content:"处理中…"}});if(W.replyState?.status==="waiting"||W.replyState?.status==="sending")return B$(W,r({toast:{type:"error",content:"正在等待文字回复,请先发送或取消回复,再选择按钮"}},!1));let H=W.buttons.find((z)=>z.id===Q);if(!H)return A(`notify-callback: notify_id=${Y.slice(0,12)}… unknown button_id="${Q}"`),B$(W,r({toast:{type:"error",content:"未知按钮"}},!1));if(!W.callbackUrl){try{n2(W.notifyId,H.id,J)}catch(z){return B$(W,r({toast:{type:"error",content:`保存反馈结果失败: ${z instanceof Error?z.message:z}`}},!1))}return A(`notify-callback: notify_id=${Y.slice(0,12)}… resolved button="${Q}" by=${J.slice(0,8)}… (no callback, pull/display)`),B$(W,{...v0(G1(W,{status:"done",buttonId:H.id,text:H.text,operatorOpenId:J}))})}l2(W.notifyId);let X=e5(Rq(W,H,J));X.catch((z)=>{A(`notify-callback: notify_id=${W.notifyId.slice(0,12)}… phase-2 rejected: ${z instanceof Error?z.message:z}`)});let V=X.then((z)=>z==="retry"?"retry":"complete").catch(()=>"retry");return B$(W,{toast:{type:"info",content:`⏳ 已选择:${H.text} · 推送中…`},__cardActionCompletion:V})}async function Rq($,Z,J){try{let Y=G1($,{status:"processing",buttonId:Z.id,text:Z.text,operatorOpenId:J});try{await r0($.messageId,Y)}catch(X){A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-1 (processing) updateCard failed: ${X instanceof Error?X.message:X}`)}let Q=await X5($,Z,J),W=Q.ok?"complete":"retry",H;if(Q.ok){let X=v9($.notifyId,Z.id,J);if(X.state==="complete")H={status:"delivered",buttonId:Z.id,text:Z.text,operatorOpenId:J,reply:Q.reply};else{W="unknown",H={status:"unknown",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:X.detail},A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… callback succeeded but tombstone is UNKNOWN: ${X.detail}`);try{await _1($.chatId,`⚠️ 通知反馈的外部回调已成功,但本地确认状态未知;为避免重复副作用,已禁止自动重试。${X.detail}`)}catch(V){A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… UNKNOWN warning receipt failed: ${V instanceof Error?V.message:V}`)}}}else H={status:"failed",buttonId:Z.id,text:Z.text,operatorOpenId:J,detail:Q.detail};try{let X=G1($,H);await r0($.messageId,X)}catch(X){A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… phase-2 (final) presentation failed: ${X instanceof Error?X.message:X}`);try{await _1($.chatId,`⚠️ 通知反馈${W==="retry"?"失败且结果卡更新失败,可重新点击":"已执行,但结果卡更新失败"}: ${X instanceof Error?X.message:X}`)}catch(V){A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… final fallback receipt failed: ${V instanceof Error?V.message:V}`)}}return A(`notify-callback: notify_id=${$.notifyId.slice(0,12)}… button="${Z.id}" ${W==="complete"?"delivered":W==="unknown"?"unknown/non-retryable":`failed: ${Q.detail}`} by=${J.slice(0,8)}…`),W}finally{i2($.notifyId)}}function a5($){return $.map((Z)=>typeof Z==="string"?Z:JSON.stringify(Z)).join(" ")}function Dq(){if(process.platform==="win32"){A("debug: inject socket skipped on Windows (dev-only feature)");return}if(typeof Bun>"u"){A("debug: inject socket skipped (Bun runtime only — npm/Node build does not include it)");return}try{if(o5(f$))_6(f$)}catch{}try{Bun.serve({unix:f$,fetch:async($)=>{if($.method!=="POST")return new Response("use POST",{status:405});if(t5)return new Response("daemon shutdown in progress",{status:503});let Z={};try{Z=await $.json()}catch{return new Response("bad json",{status:400})}if(!o5(X4))return new Response("no debug context yet — send `[DEBUG]hi` from Feishu first",{status:412});let J={};try{J=JSON.parse(Zq(X4,"utf8"))}catch(X){return new Response(`ctx read failed: ${X}`,{status:500})}let Y=String(Z.text??"");if(!Y)return new Response("text required",{status:400});let Q=`【自动化测试】:${Y}`,W=await T(J.chat_id,Q);if(!W)return new Response("sendText failed — see daemon log",{status:502});let H={sender:{sender_id:{open_id:J.sender_open_id}},message:{message_id:W,chat_id:J.chat_id,message_type:"text",content:JSON.stringify({text:Y}),create_time:String(Date.now())}};if(A(`debug: inject text=${JSON.stringify(Y).slice(0,80)} msg_id=${W}`),!uH(H,"debug"))return new Response("daemon shutdown in progress",{status:503});return new Response(JSON.stringify({ok:!0,msg_id:W}),{headers:{"content-type":"application/json"}})}});try{eB(f$,384)}catch{}A(`debug: inject socket listening at ${f$}`)}catch($){A(`debug: socket bind failed: ${$}`)}}async function Mq(){A(`lodestar-daemon: pid ${process.pid} starting`);let{buildTokenSourcesFromConfig:$}=await Promise.resolve().then(() => (q5(),DQ));$();let{refreshAllTokenSourceModels:Z}=await Promise.resolve().then(() => (G0(),U3));await Z(),S7(),b7(),C7(),f7(),g7(),await T2(),setInterval(()=>{T2()},1800000);let{reconcileTasklistDeletions:J}=await Promise.resolve().then(() => (F5(),M5));try{await J()}catch(k){A(`tasklist deletion reconcile failed: ${k instanceof Error?k.message:k}`)}let Y,Q=Date.now(),W=0,H=!1,X=null,V=1500,z=90000,G=600000,_=3,B=null,q=0,L="",P=!1,R=(k)=>{A(`[ws] rebuild requested before WS init — ${k}`)},O=(k,h=0,U=!1)=>{let y=Date.now()+h;if(B){if(P||=U,y>=q){A(`[ws] rebuild already scheduled — ${k}`);return}clearTimeout(B)}q=y,L=k,P=U,B=setTimeout(()=>{let w=L,M0=P;B=null,q=0,L="",P=!1,R(w,M0)},h)},j={error:(k)=>A(`[ws-sdk error] ${a5(k)}`),warn:(k)=>{let h=a5(k);if(A(`[ws-sdk warn] ${h}`),h.includes("no pong/inbound"))O("ping-timeout: SDK liveness watchdog fired",2000,Date.now()-Q<G)},info:(k)=>A(`[ws-sdk] ${a5(k)}`),debug:(k)=>{},trace:(k)=>{}},D=new J2.EventDispatcher({}),E=()=>{if(Q=Date.now(),W=0,X)clearTimeout(X),X=null};D.register({"im.message.receive_v1":async(k)=>{if(E(),!uH(k))throw Error("daemon shutdown in progress")}}),D.register({"card.action.trigger":async(k)=>{return E(),Lq(k)}});let x=()=>new J2.WSClient({appId:v.feishu.app_id,appSecret:v.feishu.app_secret,loggerLevel:J2.LoggerLevel.info,logger:j,wsConfig:{pingTimeout:60},handshakeTimeoutMs:1e4,onReconnecting:()=>A("[ws] reconnecting — WS lost, SDK is retrying"),onReconnected:()=>u(),onError:(k)=>R(`SDK onError: ${k?.message??k}`)});R=(k,h=!1)=>{if(H){A(`[ws] rebuild skipped (already rebuilding) — ${k}`);return}if(B)clearTimeout(B),B=null,q=0;H=!0,W++,A(`[ws] rebuild #${W} (fresh WSClient) — ${k}`);let U=Y;try{U?.close({force:!0})}catch(y){A(`[ws] rebuild: old close failed: ${y}`)}if(Y=x(),Y.start({eventDispatcher:D}).catch((y)=>{A(`[ws] rebuild start failed: ${y}`),O(`fresh client start failed: ${y}`,V,h)}),H=!1,h)b()};let b=()=>{if(X)clearTimeout(X);let k=Date.now();X=setTimeout(()=>{if(X=null,Q>=k){W=0;return}if(W>=_){A(`[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"),W=0;return}R(`verify: no event ${Math.round((Date.now()-k)/1000)}s after rebuild`,!0)},z)},u=()=>{let k=Date.now()-Q<G;A("[ws] reconnected — swapping in a fresh WSClient (cluster-routing precaution; "+`recentlyActive=${k})`),W=0,O("post-reconnect precaution",V,k)};Y=x(),Y.start({eventDispatcher:D}).catch((k)=>{A(`[ws] initial start failed: ${k}`),O(`initial start failed: ${k}`,V,!1)}),A(`lodestar-daemon: WS start requested, watching ${Q0.size} groups`);let g=15000,c=2,S=0;setInterval(()=>{let{state:k}=Y.getConnectionStatus();if(k==="connected"){S=0;return}if(k==="failed"||k==="idle"){S=0,R(`watchdog: state=${k}`);return}if(S++,A(`[ws] watchdog: state=${k} (${S}/${c})`),S>=c)S=0,R(`watchdog: stuck in '${k}' ~${Math.round(g*c/1000)}s`)},g),Dq();for(let k of dY())e5(Z2.enqueue(k.chatId,()=>K6.recover(k))).catch((h)=>A(`notify-reply recovery failed: ${h instanceof Error?h.message:h}`));pW({bind:v.notify.bind,port:v.notify.port,extraHandler:(k,h,U)=>RH(k,h,U,{service:s5,authorizeSession:(y)=>{for(let w of K1.values())if(w.acceptsAgentCapability(y))return w;return null}})}),OH(),dW(),sW(),await Vq()}var gH=!1,t5=!1,G6=null,A1=0,r5=null,IH=15000,cH=()=>{if(gH)return;gH=!0;try{let $=r5??$Z();if(E2($),$.length>0)A(`alive marker: [${$.join(", ")}]`)}catch($){A(`alive marker write failed: ${$}`)}try{_6(k0)}catch{}try{_6(f$)}catch{}},K1,s5,J4,Z2,Qq,mH,Wq,ZZ,Gq=30000,e1,K6,qq;var lH=N(()=>{gW();s();f0();a2();Q6();Q6();nW();oW();_H();DH();g5();EH();U0();I();L0();F6();wH();hH();{let $=V4(k0);if($.state==="exit")console.error(`lodestar-daemon: already running (pid ${$.pid})`),process.exit(1);if(o5(k0))try{_6(k0)}catch{}}$q(Yq(k0),{recursive:!0});zZ(k0);process.on("exit",cH);process.on("SIGTERM",()=>{Y2("SIGTERM",0)});process.on("SIGINT",()=>{Y2("SIGINT",0)});if(process.platform==="win32")process.on("SIGBREAK",()=>{Y2("SIGBREAK",0)});process.on("unhandledRejection",($)=>{A(`unhandledRejection: ${$ instanceof Error?$.stack??$.message:$}`),Y2("unhandledRejection",1)});process.on("uncaughtException",($)=>{A(`uncaughtException: ${$.stack??$.message}`),Y2("uncaughtException",1)});K1=new Map,s5=new c5,J4=new Set,Z2=new d5,Qq=new n5(30000),mH=new Set,Wq=bH({actor:Z2,key:($)=>String($?.message?.chat_id??""),execute:($,Z)=>Aq($,Z)});ZZ=vH({registry:K1,createSession:($,Z)=>new z1($,Z,{onLifecycleChange:A6,onCreateTempSession:Hq,onDisbandTempSession:Xq,onCancelAgentRuns:(J,Y,Q)=>s5.cancelSessionRuns(J,Y,Q)}),ensureChatForSession:i7,disbandChatForSessionExact:n7,chatIdForSession:p4,clearSessionConversationState:u7,registerTempSessionLease:y7,hasTempSessionLease:x7,replaceTurnAnchors:m0,runExclusive:($,Z)=>Z2.enqueue($,Z),log:A});e1=new Set,K6=aW({sendCard:i,updateCard:r0,sendText:T,dispatch:X5,onWaitingChanged:($)=>K1.get($)?.refreshPendingAsks(),log:A});qq=CH({actor:Z2,deduper:Qq,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=G$(String($?.action?.value?.notify_id??""));if(J)return J.chatId}return String($?.context?.open_chat_id??"")||"__notify_global__"},execute:Pq,present:Kq,presentExecutionFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");A(`handleCardAction ${J}: ${Z instanceof Error?Z.stack??Z.message:Z}`),await Bq($,Z)},presentPresentationFailure:async($,Z)=>{let J=String($?.action?.value?.kind??"unknown");A(`card-action presentation ${J}: ${Z instanceof Error?Z.message:Z}`),await _1(String($?.context?.open_chat_id??""),`⚠️ ${B6(J)}已执行,但结果呈现失败。`)},businessSucceeded:($,Z)=>{if(typeof Z?.__businessOk==="boolean")return Z.__businessOk;return $?.action?.value?.kind==="permission"&&$?.action?.value?.decision==="deny"||Z?.toast?.type!=="error"},completion:($,Z)=>{let J=Z?.__cardActionCompletion;return J&&typeof J.then==="function"?J:null},track:($)=>{e5($)},onBackgroundError:($)=>{A(`card-action background: ${$ instanceof Error?$.stack??$.message:$}`)},responses:{accepted:($)=>({toast:{type:"info",content:`⏳ ${B6(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}})}});Mq().catch(($)=>{A(`boot fatal: ${$}`),Y2("boot fatal",1)})});L0();F6();import{existsSync as iH,unlinkSync as Uq}from"node:fs";var n0={reset:"\x1B[0m",bold:"\x1B[1m",yellow:"\x1B[33m",green:"\x1B[32m",red:"\x1B[31m"};async function Oq(){if(!iH(q0)){if(process.stdin.isTTY){console.log(),console.log(`${n0.bold}${n0.yellow}Lodestar: 未找到配置, 启动安装向导...${n0.reset}`);let{runSetup:Z}=await Promise.resolve().then(() => (RZ(),jZ));await Z();return}console.error(`${n0.red}Lodestar: 未找到配置 ${q0}${n0.reset}`),console.error(`请在交互式 cmd / PowerShell 里运行 ${n0.green}lodestar-setup${n0.reset} 完成首次配置 (或直接运行 ${n0.green}lodestar-daemon${n0.reset} 也会触发同一个向导)。`),process.exit(1)}let $=V4(k0);if($.state==="exit")console.error(`${n0.yellow}Lodestar: 已经有一个 daemon 在运行 (pid ${$.pid})${n0.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(` • 误判 / 已经死了: 手删 ${k0} 后再跑`),process.exit(1);if(iH(k0))try{Uq(k0)}catch{}await Promise.resolve().then(() => (lH(),Fq))}Oq().catch(($)=>{console.error("lodestar fatal:",$?.message??$),process.exit(1)});